笔记:莫队

莫队学习笔记

参考了 OI Wiki ,其实是一个大合集!

莫队算法是基于暴力的算法,通过将询问区间做特殊排序,在朴素转一下能得到优秀的复杂度。

普通莫队

对于大小为 \(N\) 的序列问题,设询问为 \([l_1,r_1],[l_2,r_2] \cdots [l_M,r_M]\) 。将序列分块,询问按照:以 \(l\) 所在块为第一关键字,\(r\) 为第二关键字排序。

考虑从一个询问转移到另一个询问,将当前的查询区间 \([l,r]\) 直接平移到下一个查询区间:例如依次加入 \(r+1,r+2\)\([l,r+2]\),并删除 \(l\)\([l+1,r+2]\)

\(n,m\) 同阶时取块长 \(T=\sqrt{n}\) 可以在 \(O(n\sqrt{n})\) 的时间内解决。

复杂度

这里只是粗略的推断一下这么做的复杂度:

假设块大小为 \(T\) ,设每个块内的询问次数为 \(x_i\) ,假设移动成本为 \(c\) ,即延长或缩短当前区间的复杂度,序列长 \(n\) ,询问次数 \(m\)

设每一个块内的移动次数总数是 \(f_i\) ,则总复杂度大致为 \(c\sum f_i\) ,这里 \(c\) 是常数,不妨假定 \(c=1\) ,则复杂度为 \(\sum f_i\)

考虑一个块内的最劣情况,由于单个块内按 \(r\) 排序,那就让 \(r\) 增到最大处 \(n\) ,块内的 \(l\) 没有要求,那就反复安插在块首和块尾。并且最大化到下一个块的转移,\(l\) 是一路枚举到 \(n\) 的,\(r\) 考虑每次还要从上一块的 \(n\) 移动到块首再移动到块尾。

那可以粗略写出 \(f_i=2(n-T)+x_iT\) ,前者为 \(r\) 的移动成本,后者为 \(l\) 的移动成本(最劣情况每次移动一个块长)。

考虑到块数量为 \(\frac{n}{T}\) ,那 \(\sum f_i=\frac{2n^2}{T}+Tm-2T \frac{n}{T}\) ,最后一个式子就是 \(n\) 排除掉,\(\sum f_i=\frac{2n^2}{T}+Tm\) ,这是基本不等式,当 \(T=\sqrt{\frac{2n^2}{m}}\) 时得到最小值 \(n\sqrt{m}\) ,省略了常数,当 \(n,m\) 同阶时一般 \(T=\sqrt{n}\) 就可以了。

奇偶优化

复杂度推到中我们发现一个块转移到另一个块要把 \(r\) 指针从 \(n\) 移回块中又要移到 \(n\) ,那么我们按照块编号的奇偶顺序将 \(r\) 按照升序/降序分开排序,移动次数就会减少许多。

值域分块

莫队的移动次数和查询次数是不平衡的,移动的代价是 \(n\sqrt{n}\) ,而查询代价只有 \(n\) ,因为答案都在移动时计算了,有时我们可以将移动和查询的单次代价间做一个不均衡处理,使得总体变得均衡。

对于一些特定的问题,值域优化可以平衡二者复杂度,以下面的题为例:这里

题意转化下来是求序列每个询问区间中,所有不超过 \(x_i\) 的数的出现次数阶乘的积,即 \(\prod_1^{x_i} cnt_x!\)

例如用树状数组维护区间答案,修改查询都是 \(\log\) ,瓶颈复杂度 \(O(n\sqrt{n}\log n)\)

用分块维护值域查询,我们发现删减数的操作是 \(O(1)\) 的,查询是 \(O(\sqrt{n})\) ,和树状数组区别在修改和查询的均衡策略上,此时移动和查询复杂度都是 \(O(n\sqrt{n})\) ,就比较优秀了。

带修莫队

莫队还能带修改?

询问改成 \([l,r,t]\) ,第三维表示修改次序,把二维询问转化成三维的。

排序方法为第一关键字以 \(l\) 所在块,第二关键字以 \(r\) 所在快,第三关键字 \(r\) 升序排列。

证明比较繁琐,参考了 OI WIKI 的证明,在 \(T=\frac{n^{2/3}t^{1/3}}{m^{1/3}}\) 时复杂度为 \(O(n^{2/3}m^{1/3}t^{1/3})\) ,一般取 \(T=n^{2/3}\)

回滚莫队

某些情况加一个数容易实现,删除一个数不容易实现。

按照普通莫队的排序方法排序,这样在一个块内,右端点由于升序扩展只有加操作。

我们以当前块的右端点作为左端点,以左端点在块右侧的区间构成基准区间。

处理每个询问时,都从这个基准区间扩展到目标的左端点,得到答案后撤销左端点的修改,即将当前区间再返回到基准区间,处理下一条修改。

唯一的问题在于若左右端点在同一个块内,这样的扩展不合法,此时暴力扫描一遍求出答案即可。

可以发现移动次数分析和普通莫队基本是一样的,可以沿用下来,只是常数会比较大,并且奇偶优化不能使用,因为我们要保证右端点的操作升序,这样才能只有添加操作。

若当前块的所有询问都完成了,则重新初始化基准区间到下一个块,初始右端点为下一个块的右侧减一。

对于只能删除不能添加的情况是等价的。

posted @ 2025-06-11 16:18  蒻蒻虫  阅读(17)  评论(0)    收藏  举报