CF981E Addition on Segments

发布时间 2023-10-23 09:51:07作者: 御坂夏铃

将操作按右端点从小到大排序,这样对于当前值相同的点,只有最右边的那一个是有用的。

\(f_i\) 表示当前值为 \(i\) 最靠右的点的位置,转移直接暴力判断能否取 \(\max\) 即可,时间复杂度 \(O(nq)\)

这个东西看起来就不好优化。

不妨调换状态和值,令 \(f_{i,j}\) 表示当前位置 \(i\) 上值是否可能为 \(j\)这样操作的顺序就无关紧要了,对于每个操作暴力枚举区间内的点转移,时间复杂度 \(O(n^2q)\),用 bitset 可以优化到 \(O(\frac{n^2q}{w})\)

注意到查询可以放在最后,考虑线段树分治。将每个操作打到线段树 \(O(\log n)\) 个结点上,用 vector 存下 \(x\)。最后 DFS 一遍,把路径上的 \(x\) 转移进 bitset 推到叶子结点上,时间复杂度 \(O(\frac{nq\log n}{w})\)

本质其实就是利用操作的非即时性和无序性把共有操作尽量一起做掉。