莫队二次离线
普通莫队在维护一些东西的时候,移动 \(l,r\) 指针的复杂度不是 \(O(1)\),可能会导致复杂度不正确。莫队二次离线,顾名思义,就是将普通莫队转移的过程再次拆式子离线处理。假设普通莫队移动 \(l,r\) 指针的复杂度为 \(O(k)\),那么莫队二次离线的科技就把总复杂度从类似 \(O(n\sqrt nk)\) 变成了 \(O(nk+n\sqrt n)\) 之类状物。
P4887 【模板】莫队二次离线(第十四分块(前体))
普通莫队做法,维护一个桶 \(\text{buk}(i)\) 表示数 \(i\) 有多少个,查询时对于新加的数 \(x\) 查询 \(\sum_{v\in S}\text{buk}(x\oplus v)\) 即可,其中 \(S\) 就是满足二进制下 \(1\) 的个数为 \(k\) 的数的集合。复杂度 \(O(n\sqrt n\binom{14}k)\),不能通过。
考虑新加进来的 \(a_{r+1}\) 对原来的 \([l,r]\) 这一区间所作出的贡献,记为 \(f(a_{r+1},l,r)\)。差分,拆分为 \(f(a_{r+1},1,r)-f(a_{r+1},1,l-1)\)。进一步,设当前的右端点从 \(r\) 移动到了 \(r'\),那么要统计的就变成了
再拆成前后两部分考虑。第一部分显然可以按照与普通莫队同样的做法预处理 + 前缀和。第二部分不好在线处理,于是再次离线,把一次询问所要统计的 \(\sum f(a_i,1,l-1)\) 统一挂到 \(l-1\) 上,最后统一查询。具体地,仍然维护一个桶,但表示的内容变成:\(\text{buk}(v)\) 表示与 \(v\) 异或得到的数属于 \(S\) 的数的个数。然后统计是容易的。
然后右端点移动的情况就统计完了。左端点移动的情况同理,要再统计一遍。
最后我们上面算的都只是答案相对于上一个答案的增量,于是做完之后要进行一遍前缀和。Code。
P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II
与上一道题同理。这题需要我们区间统计逆序对,仍然拆成两个部分。但是这题处理第二部分时如果用树状数组复杂度是错的,所以需要用值域分块实现 \(O(1)\) 查询。
注意这题的数有重复,所以统计逆序对的时候容易被各种 \(+1/{-1}\) 创死。

浙公网安备 33010602011771号