[学习笔记]莫队学习笔记[未完待续]
莫队学习笔记[未完待续]
000 引入
莫队,由前国家队队长莫涛发明,是一种区间维护区间状态的离线也可在线的算法。
其核心是对询问进行分块,并适当地调整询问顺序。
001 普通莫队
算法流程
我们把\(\sqrt{n}\)作为块大小进行分块并编号。
再把左端点所在块编号作为第一关键字,右端点作为第二关键字且升序排序。
然后按照顺序依次解决所有询问即可。
具体解决问题遵循以下步骤:
-
移动一步区间,计算答案增量,进行\(O(n\sqrt{q})\)次,单次\(O(a)\)
-
移动一步区间,重新维护数据结构,进行\(O(n\sqrt{q})\)次,单次\(O(b)\)
-
到达目标区间,计算答案,进行\(O(q)\)次,单次复杂度\(O(c)\)
算法复杂度
对于维护区间状态问题,如果我们已知区间\([l, r]\)状态的情况下,我们能在\(O(T)\)的时间内使得该区间的左或右端点移动一格并维护出相应的状态,那么莫队算法的复杂度即为\(O(n\sqrt{n}\cdot T)\)
代码实现
while (l > q[i].l) add(a[--l]);
while (r < q[i].r) add(a[++r]);
while (l < q[i].l) del(a[l++]);
while (r > q[i].r) del(a[r--]);
当前处理的到底是\(l\)还是\(r\)并不重要,重要的是当前区间到底是扩大还是缩小。
注意扩大区间一般放在缩小区间的前面,这样是为了防止区间长度变成负数情况的出现。
题目练习
002 带修莫队
003 回滚莫队
004 树上莫队
005 二次离线莫队
006 卡常技巧
inline和register
多用吧,有递归的时候千万别用inline
调整块大小
在考场上,推出理论的最优块大小后,可以尝试在最优值的附近稍微调整块的大小。
奇偶数升降排序
一般我们排序是把左端点所在块编号作为第一关键字,右端点作为第二关键字且升序排序。
考虑优化,我们可以在左端点所在块编号是奇数时,右端点升序,当左端点所在快编号是偶数时,右端点降序。
这样能快是因为指针移到右边后不用再跳回左边,而跳回左边后处理下一个块又要跳回右边,这样能减少一半操作,理论上能快一倍