莫队算法

普通莫队

按照左端点所在块为第一关键字,右端点为第二关键字排序。然后按照暴力做即可。

B B B表示块的大小, n n n表示序列长度, m m m表示询问数,时间复杂度分析:

  1. 左端点 l l l移动次数最多是 询问数 * 块大小: O ( m B ) O(mB) O(mB)
  2. 右端点 r r r移动次数最多是 块个数 * 总长 O ( n 2 B ) O(\frac{n^2}{B}) O(Bn2)

于是这个的时间复杂度为 O ( m B + n 2 B ) O(mB+\frac{n^2}{B}) O(mB+Bn2).

根据基本不等式可得这个对勾函数当 B = n m B=\frac{n}{\sqrt{m}} B=m n时时间复杂度最小,为 O ( n m ) O(n\sqrt{m}) O(nm ),总时间复杂加上排序就是 O ( n m + m l o g m ) O(n\sqrt{m}+mlogm) O(nm +mlogm)

应用

百度即可。

带修莫队

经典例题:https://jzoj.net/senior/#main/show/4594

核心思想是把版本嵌套在普通莫队上,每次要注意版本对区间的影响

即先更新当前版本对当前区间的影响,如果版本往前,那么查看是否会对当前区间有影响,有影响则更新,版本往后同理。

最后再跟普通莫队一样,在当前版本上进行左右断点的移动。

排序的方式是:以 n 2 3 n^{\frac{2}{3}} n32为一块,一共将序列分为 n 1 3 n^{\frac{1}{3}} n31块。排序第一关键字是左端点所在块编号,第二关键字是右端点所在块编号,第三关键字是对应版本。

模板类似:

for (int i = 1; i <= m; i ++) {
        while (K < q[i].k) Change(++ K);
        while (K > q[i].k) Change(K --);
        while (R < q[i].r) Add(++ R);
        while (L > q[i].l) Add(-- L);
        while (R > q[i].r) Del(R --);
        while (L < q[i].l) Del(L ++);
        res[q[i].pos] = ans;
}

时间复杂度分析(与上面相同 B B B表示块大小,且假设 n , m n,m n,m同阶):

  1. 版本移动:最多有 ( n B ) 2 {(\frac{n}{B})}^2 (Bn)2 r r r块,对于每个 r r r块 版本最多移动 n n n次,所以复杂度是 O ( n 3 / B 2 ) O(n^3/B^2) O(n3/B2).
  2. 右端点 r r r移动:由于移动递增,所以 r r r块相同时,最多移动 B B B次,时间复杂度是 O ( m B ) O(mB) O(mB) r r r块不同时,由于只有 n / B n/B n/B l l l块,所以最多移动 n 2 B \frac{n^2}{B} Bn2次,总的复杂度是 O ( m B + n 2 B ) O(mB+\frac{n^2}{B}) O(mB+Bn2).
  3. 左端点 l l l移动:每次最多移动 B B B个,时间复杂度是 O ( m B ) O(mB) O(mB)

n , m n,m n,m同阶时复杂度为 O ( n B + n 2 B + n 3 B 2 ) O(nB+\frac{n^2}{B}+\frac{n^3}{B^2}) O(nB+Bn2+B2n3),设 B = n x ∣ ( 0 &lt; x &lt; 1 ) B=n^x|(0\lt x\lt 1) B=nx(0<x<1),那么复杂度可以写成 n max ⁡ ( x + 1 , 2 − x , 3 − 2 x ) n^{\max(x+1,2-x,3-2x)} nmax(x+1,2x,32x),易知 x = 2 3 x=\frac{2}{3} x=32时时间复杂度最小,为 O ( n 5 3 ) O(n^{\frac{5}{3}}) O(n35).

树上不带修莫队

一般解决树上路径问题。

这个有一种很好的解决办法,即利用括号序。

对于一段路径 x , y x,y x,y,如果其 l c a lca lca不是它们中一点,则可以把路径对应到原序列上

序列中 x x x右括号位置到 y y y左括号位置中出现一次的点,再加上 x x x y y y l c a lca lca

否则假设 y y y l c a lca lca,那么可以对应到原序列上

序列中 y y y左括号位置到 x x x左括号位置中出现一次的点

这样就转化为普通莫队了。

树上带修莫队

根据前两个知识即可。

例题:BZOJ3052: [wc2013]糖果公园

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值