P8257 [CTS2022] 普罗霍洛夫卡 解题报告:
题意
给定序列 \(a\),\(m\) 次查询一个区间所有的子区间颜色数量异或和。
\(1\leqslant n,m\leqslant 4\times 10^5\)。
分析
扫描线一下就变成了区间加一,区间历史版本异或和查询。
异或具有自反性,一个全部是 \(x\) 的段异或值要么是 \(0\) 要么是 \(x\),也就是我们可以在修改的时候更新历史版本异或和,查询的时候单独处理最后一次就好了。
手玩一下可以得到,对 \(x\) 加一,值会异或上 \(2^{\text{lowbit}(x)+1}-1\)。
再仔细观察一下,可以发现我们维护的序列递增,且相邻最多差 \(1\)。于是我们以块长 \(B=2^k\) 对序列分块,散块暴力重构,可以发现整块进行 \(B\) 次整体加一,某个位置异或的值大于 \(B\) 的事件只会发生 \(B\) 次,那么每个块暴力维护这些事件均摊是 \(O(1)\) 的。
而异或的值小于 \(B\) 的修改可以考虑提前预处理出结果,每个块维护一下整体加标记。直接预处理复杂度肯定不对,我们可以类似 sos dp 做到 \(B+\frac{B}{2}+\frac{B}{4}+\cdots=O(B)\) 的复杂度。
查询很简单,于是就做到了 \(O(n\sqrt n)\) 的时空复杂度,不难发现逐块处理空间可以做到线性。
代码
咕了,有时间写。