我是鸽子/cy
Description
维护一个长度为 $n$ 的序列$a_n$,$q$次操作.
要求支持单点赋值、整体赋值、整体加、整体乘、单点查询和整体求和。
$n \leq 10^9, q \leq 10^5, 0 \leq a_i \leq 10^9$.
Samples
Input #1
1 | 7 |
Output #1
1 | 2816930 |
Solution
$\rm Subtask 1$直接随便拿一个平衡树就好了。
全部数据的话,序列长度极大,有$10^9$, 显然要求执行操作复杂度$\mathcal O(1)$.
注意到本质不同的操作只有$10^5$个,那么可以把涉及的编号拿出来离散化一下即可。
因为所有的区间操作全部是针对整个数列的,考虑类似于分块打标记的方式,我们维护四个标记:
- $\rm add$ 全局加标记,$\rm mul$ 全局乘标记, $\rm sum$ 全局和标记, $\rm inv$ 逆元标记。
针对操作二,那么就有add += val, sum += n * val
.
针对操作三,那么就有add *= val, mul *= val, sum *= val
.
针对操作四,之前的修改全都白费了,就有add = 0, mul = 1, sum = n * val
.
针对操作五,那么就有ans += mul * a[x] + add
.
操作六就直接在答案上累加sum
标记即可。
考虑操作一, 由于我们要考虑标记,所以不能把$\rm a_x$直接赋值为$\rm val$, 假设我们这么干了,那么我们统计的答案就是mul * val + add
.
但是实际上查询这个点,我们直到结果应该是val
, 那么可以得到val_real = (val - add) * inv
.
注意进行这个操作的同时,全局和标记也需要修改,即sum += val_real - val
.
其他的就是注意随地取模,注意下细节就好了,时间复杂度$\mathcal O(q \log q + tq)$
Code
1 | /* Headers */ |