【总结】 莫队算法

前言

机房中的各位神仙都会莫队就我不会,然后如果有些题实在想不出也可以用这个做一下。

思路

如果一些操作可以在知道\(Ans(l,r)\)的情况下,\(O(1)\)的时间内求出\(Ans(l-1,r),Ans(l+1,r),Ans(l,r+1),Ans(l,r-1)\),那么就可以用莫队求解。

  1. 将操作离线
  2. 按照分块的思路排序(这是保证复杂度合法的关键)
  3. 对于每一个询问不断更新
  4. 总结答案,重新按照编号排序输出

复杂度证明

在此之前,给出每一个区间询问的排序方法

int bl[maxn];//bl数组用来记录每一个点属于哪个块
struct node{
    int l,r;
}ques[maxm];
bool cmp(node a,node b){
    if(bl[a.l]==bl[b.l])return a.r<b.r;
    return a.l<b.l;
}

因为每一组的询问左界都是在一个块里面的,所以左界的更新不会超过\(sqrt(n)\)
如果左界不在一个块里面的话,复杂度就是\(O(m-sqrt(n))\)的。
又因为块只有\(sqrt(n)\)个,所以一定是可以的(想一想,为什么)

例题

Problem1

国家集训队-小Z的袜子


考虑拆分式子,发现本质是维护一个区间的平方和,然后就可以用莫队计算。

Problem2

国家集训队-数颜色
考虑这是一个带修改的莫队,怎么办呢?

带修改操作的莫队

每一次询问我们都是排序后一个一个做的对吧,那么我们可以不断的按照修改操作的顺序来修改这些颜色,如果少了就接着改,多了就改回去。
思路和莫队差不多,只是多了两个循环,判断改多了还是改少了。

Problem2

让我们回到那个问题,接着思考怎么做。
有了上面的思路,直接就可以写了,记录一下每一个询问前最后一次修改的编号,然后不断修改就好了。

后话

有没有什么神仙可以告诉我HH的项链在洛谷怎么过(用莫队)啊。80分实在是没救了。
块的大小大家可以将\(sqrt(n)\)\(n^{\frac{2}{3}}\)拍一下。

posted @ 2018-12-18 15:12  cjgjh  阅读(159)  评论(0编辑  收藏  举报