题目
题目描述
Z
X
Y
\sf ZXY
ZXY 是一个喜欢打树套树的妹妹。可是别人的常数都是
∫
1
+
∞
1
x
2
d
x
\int_{1}^{+\infty}\frac{1}{x^2}\rm{dx}
∫1+∞x21dx ,她的常数是
∫
1
+
∞
1
x
d
x
\int_{1}^{+\infty}\frac{1}{x}\rm{dx}
∫1+∞x1dx ,所以
T
L
E
\tt TLE
TLE 是她的老朋友。
她决心改变这一局面,于是出了一道不需要树套树的数据结构题。你需要维护三种操作:
- 区间模 m m m 。即,对于 i ∈ [ l , r ] , a i = a i m o d m i\in[l,r],\;a_i=a_i\bmod m i∈[l,r],ai=aimodm 。
- 区间加 v v v 。即,对于 i ∈ [ l , r ] , a i = a i + v i\in[l,r],\;a_i=a_i+v i∈[l,r],ai=ai+v 。
- 区间求和。即,输出 ∑ i = l r a i \sum_{i=l}^{r}a_i ∑i=lrai 。
m m m 为事先给定的常量。
数据范围与提示
n
≤
2
×
1
0
5
,
m
≤
1
0
5
,
q
≤
1
0
4
n\le 2\times10^5,\;m\le 10^5,\;q\le10^4
n≤2×105,m≤105,q≤104 。
为了节约你的时间(其实是湘妹的大整数比别人慢五倍 ),输出取模
998244353
998244353
998244353 。
思路
别说树套树了,连平衡树都不需要 ヾ(๑╹◡╹)ノ"
修改越恶心,分块 越开心,就这么简单。(如果你不知道这句话,背诵并默写全文,看看
Y
n
o
i
\tt Ynoi
Ynoi 去吧。)
考虑另开一个数组维护 a m o d m a\bmod m amodm 的区间和,这样取模操作来临时,直接拷贝就好了。现在看看区间加会如何影响余数吧——对于 a < m − v a<m-v a<m−v 是直接 a = a + v a=a+v a=a+v ;对于 a ≥ m − v a\ge m-v a≥m−v 则是 a = a + v − m a=a+v-m a=a+v−m 。只要知道两种 a a a 的数量,我就能维护区间和。
用桶来维护吗?开一个 O ( m ) \mathcal O(m) O(m) 的桶统计每种数字的数量,或许再求一个前缀和,可行吗?或许是可行的,不过需要用树状数组维护——因为区间加的边角料需要重构块。至于区间加,可以看成零点(即数轴)的移动,把零点存下来即可。
块的整体修改,打什么标记呢?先加再取模会合成一个取模,标记为 x = ( x + a ) m o d m + b x=(x+a)\bmod m+b x=(x+a)modm+b 即可。
用
B
B
B 表示块的长度,则复杂度为
O
(
q
B
log
m
+
q
⋅
n
B
⋅
log
m
+
n
log
m
)
\mathcal O\left(qB\log m+q\cdot \frac{n}{B}\cdot \log m+n\log m\right)
O(qBlogm+q⋅Bn⋅logm+nlogm)
取 B = n B=\sqrt{n} B=n 有最优复杂度 O ( q n log m + n log m ) \mathcal O(q\sqrt{n}\log m+n\log m) O(qnlogm+nlogm) ,其实挺慢的。
我有句话想对你说,但是话到嘴边又说不出口。(你居然猜到了谜底!)其实还有一种做法是,维护每个块排序后的结果。但是复杂度不变。
代码
Network connection error. Please try it later.