莫队算法

· · 个人记录

普通莫队

普通莫队不支持修改。

莫队就是直接将询问离线下来,根据某种顺序排序之后,可以直接用比较好的效率暴力以得到答案。而如何排序也就十分重要。

如果只是以左端点排序的话,右端点有可能要跨很远,复杂度就直接O(mn)了,爆炸。

所以我们可以把左端点分块,再把右端点在每个块之内排序。

这样可以保证在每一个块内,右端点移动不减,因此最多n次,而一共sqrt(n)个块,所以右端点移动的复杂度是sqrt(n).

同时,左端点可能在块内不停地跳,所以可能跳sqrt(n)^2=n次,而一共sqrt(n)个块,因此左端点移动的复杂度也是sqrt(n).

所以总的复杂度也就是O(n*sqrt(n))了。这样就可以暴力地求了。

当然这个复杂度建立在一个基础之上:每一次l,r的加加减减都是O(1)的。

所以普通莫队就是如此。

例题:

P1494 满分代码

P2709 满分代码

P1972 90分代码,最后一个点卡不过去orz..

带修莫队

应该是和普通莫队差不多的,就是在普通莫队基础之上同时记下本次查询操作之前的修改次数,然后也用一个指针跳就可以了。这里就可以也在块的内部在r的基础上再根据修改次数排个序了。这里块的大小最佳是n^(2/3).

例题:

P1903 满分代码