莫队学习笔记
莫队
莫队是个好东西
莫队简介
莫队算法是由莫队提出的。虽然他提出之前该算法已经在Codeforces中小范围流传,但是莫涛是第一个详细总结莫队算法的人。
莫队作用
莫队是一种离线处理静态区间查询的一类方法。时间复杂度为
普通莫队
形式
钦定
解释
离线后按照特定的方式排序,顺序处理每个询问,暴力从上一个区间的答案转移到下一个区间的答案(一步一步的将
那么有人就要问了:这样子的时间复杂度在
实际上不是。注意到上面描述作用时,有一个
排序方法
我们把问题变成一个简单的理解就是在平面坐标系上游走,有
很容易想到,如果
但是我们的时间复杂度得到优化了吗?如果块长为
tips:关键字的意思是指从小到大排序时的依据,也就是按照谁的值来排序的。
代码
处理每个询问(先扩张在缩小,避免区间为空)
// 回答 [l,r],当前在 [L,R]
while(L > l) add(-- L);
while(R < r) add(++ R);
while(L < l) del(L ++);
while(R > r) del(R --);
排序方法(重载)
struct node {
int l, r, id;
//b[x] 表示 x 所在的块
bool operator < (const node &x) const {
if (b[l] ^ b[x.l]) return l < x.l;
else return r < x.r;
}
};
优化
过程
这里我们要用到奇偶化排序。
什么是奇偶化排序?奇偶化排序即对于属于奇数块的询问,
建议自己模拟一下,加深理解。
代码
struct node {
int l, r, id;
bool operator<(const node &x) const {
if (l / unit ^ x.l / unit) return l < x.l;
if ((l / unit) & 1) return r < x.r;
return r > x.r;
}
};
习题
P1494 [国家集训队] 小 Z 的袜子
带修改莫队
普通莫队处理的都是静态问题,如果加上单点修改还能做吗?
充分发挥人类智慧。 我们可以认为是多了“时间”这一个维度,也就是询问形如
也就是变成了在一个三维的坐标系中游走,但是我们需要对这样的询问再后再一个排序的方式使其复杂度优于暴力。
其实我们只需要把时间也看成指针。特别地,如果加入的修改在当前区间里面,应当立刻对区间答案进行修改处理影响。
先按
那么复杂度又是多少呢?
钦定
P1903 [国家集训队] 数颜色 / 维护队列
回滚莫队
我们发现无论是普通莫队还是带修改莫队,都可以快速地对区间进行扩展或者收缩。
如果强行想用莫队做区间最大值等增加或删除无法实现的问题怎么办?
当只增加和删除中的一个不可实现时,就可以使用回滚莫队
核心
只能使用一种操作,就用一种操作,剩下的用回滚莫队来解决。
形式
假设现在只能区间扩展,不能删除(只删除不扩展是类似的)。
那么,我们怎么样让
走了之后我们所做的操作不叫删除,叫回退。回退就是我们知道我们走的时候的状态,然后一步一步回到这个状态。
举个栗子:比如你修改了
参考文献及鸣谢
本文部分内容参考oi-wiki上的内容。
特别感谢@摸鱼酱@Aurelia_Veil@chenyixuan18提供的宝贵意见。
欢迎在下方留言哦。