Loading

分块算法的简单应用

莫队

莫队是分块的一个应用,即对询问分块。

思想:

  • 通过移动端点的方式将一个询问转移至另一个,从而减少重复计算。
  • 对询问分块排序以平衡左右端点移动复杂度。

过程:

  • 将序列分成若干块,然后将询问离线;
  • 以左端点所属块的编号为第一关键字,右端点位置为第二关键字进行排序;
  • 每次通过扩张/删除左右端点的操作将左右端点转移至当前询问,更新答案。

条件

  • 支持离线
  • 可以\(\Omicron(1)\)(或是较小复杂度)移动端点(包括修改状态和更新答案两部分的复杂度)

莫队时间复杂度分析

\(n,m,\)同阶时,\(k\)维莫队复杂度易证为\(n^{\frac{k-1}{k}}\).

二维莫队:

\[设块大小为S,则复杂度为:\Omicron(m\times S+n\times\frac{n}{S})\\ 当左右复杂度平衡时:m\times S=\frac{n^2}{S}\\ S^2=\frac{n^2}{m}\\ S=\frac{n}{\sqrt{m}}\\ 最终复杂度:\Omicron(\frac{m\times n}{\sqrt m}+n\times\sqrt m)= \Omicron(n\sqrt m)\\ \]

当扩展到更高维的情况时,假设除\(m\)外所有维度大小均为\(n\).

三维莫队(带修莫队):

\[设块大小为S,则复杂度为:\Omicron(m\times S+n\times(\frac{n}{S})^2)\\ 当左右复杂度平衡时:m\times S=\frac{n^3}{S^2}\\ S^3=\frac{n^3}{m}\\ S=\frac{n}{m^{\frac{1}{3}}}\\ 最终复杂度:\Omicron(m\times\frac{n}{m^{\frac{1}{3}}}+\frac{n^3\times m^{\frac{2}{3}}}{n^{2}})=\Omicron(n\times m^{\frac{2}{3}})\\ \]

归纳以上过程可得出:

\[\lbrack K维莫队\rbrack—\lbrack 块大小S=\frac{n}{m^{\frac{1}{k}}}\rbrack—\lbrack时间复杂度\Omicron(n\times m^{\frac{k-1}{k}})\rbrack \]

带修莫队(单点修改)

考虑将时间作为第三维直接转换为三维莫队处理即可。

回滚莫队

如果支持快速扩张而不支持快速删除,可以使用回滚莫队。

过程

  • 对于左右端点在一块内的询问,直接暴力处理。

  • 首先将每个块对应的询问单独处理,这样只有左端点的右移需要删除。

  • 初始时左端点位于块的最右端点,考虑每次移动后暴力将左端点造成的所有更新和贡献撤销,使得左端点回到原位置,以规避删除操作。

复杂度和其他过程同普通莫队。

条件

  • 虽然不能快速删除,但是可以快速撤销,或是可以方便的保存原状态。

比如插入复杂度需要均摊的情况就可能因为撤销操作而导致错误。

特殊情况

有些时候不能插入,但可以快速删除,也能用相似的方法进行处理。

莫队二次离线

在移动端点时,可以膜拜\(\operatorname{\color{black}{M}\color{red}{YY}}\)

有些情况下在移动端点时,可以做到\(\Omicron(1)\)查询,却只能\(\Omicron(k)\)修改,那么利用二次离线可以将整体复杂度优化至\(\Omicron(nk+n\sqrt n)\).

核心思想是将端点的移动再次离线,然后扫描线统计答案。

我们考虑当右端点移动时产生的贡献:

\(\operatorname{f}(x,[l,r])\)\(x\)\([l,r]\)的贡献。

假设原先的区间为\([l,r]\),移动至\([l,k]\),考虑差分统计其中某个点\(x\in[r+1,k]\)的贡献:

\[\operatorname{f}(x,[l,x])=\operatorname{f}(x,[1,x])-\operatorname{f}(x,[1,l-1]) \]

观察到式子左边只\(x\)有关,可以预处理。

式子右边\(x\)的取值是连续的所以这样处理:

  • 直接记录区间\([r+1,k]\),离线。
  • 从左到右扫描,更新当前位置信息。
  • 当扫描到\(l-1\)时,暴力扫描区间\([r+1,k]\)中的每个数统计贡献。
  • 注意到\(\operatorname{f}(x,[1,l-1])\)不仅对当前区间有贡献,对之后的区间也有贡献,因此把他映射到询问数组上做一趟前缀和。

接下来考虑情况类似的左端点移动:

原区间\([l,r]\),移动至\([k,r]\),点\(x\in[k,l-1]\)的贡献:

\[\operatorname{f}(x,[x,r])=\operatorname{f}(x,[1,r])-\operatorname{f}(x,[1,x-1]) \]

我们可以如法炮制,预处理式子右边,扫描统计式子左边。

时间复杂度\(\Omicron(nk+n\sqrt n)\),空间复杂度\(\Omicron(n)\).

例题

luogu4887 第十四分块(前体)

考虑直接普通莫队,开个桶,莫队,每次修改的时候把所有和自己\(\operatorname{xor}\)结果有\(k\)\(\textbf{1}\)的位置加上1,每次修改最多需要高达\(\binom{14}{7}=3432\)次操作,但是查询的复杂度只有\(\Omicron(1)\),因此使用二次离线。

注意到这题里面一个数是不能和自己产生贡献的,所以\(\operatorname{f}(x,[1,x])\)直接拿\(\operatorname{f}(x,[1,x-1])\)代替,最后再特判即可。

时间复杂度\(\Omicron(3432n+n\sqrt n).\)

莫队的一个经典应用

多询问组合数前缀和

\[\operatorname{F}(n,m)=\sum_{k=0}^{m}\binom{n}{k} \]

询问\(T\)\(\operatorname{F}(n,m)\)\(n,m,k\)同阶。

利用加法恒等式(\(\binom{n+1}{k}=\binom{n}{k}+\binom{n}{k-1}\))可以将\(n,m\)\(\Omicron(1)\)的时间内移动,于是就能利用三维莫队以\(\Omicron(n^{\frac{2}{3}})\)的复杂度规划出一条路径。

有关莫队的内容就到此为止了。

posted @ 2020-12-26 16:18  SmilingKnight  阅读(71)  评论(0)    收藏  举报