莫队
使用场景
- 离线算法;
- 区间询问不断修改。
- 能用 \(O(1)\) 的时间复杂度从 \([l, r]\) 到 \([l + 1, r]\) 或者 \([l, r - 1]\)。
原理
原问题可以转化为为建立一个坐标轴,对于一个询问 \((l, r)\),相当于点 \((l, r)\),从一个询问 \((a, b)\) 到 \((c, d)\),可以理解为点 \((a, b)\) 到 \((c, d)\) 的曼哈顿距离,\(Q\) 次询问的转移构成一棵生成树,当取曼哈顿距离的 MST(最小生成树),转移总代价最小。
实现
- 将询问离线,分块;
- 将询问排序,第一关键字左端点,第二关键字右端点;同一个块里面的,按照右端点排序;不是同一个块里面的,按照左端点排序。
- 维护双指针 \(x, y\),对于一次区间询问 \([qx, qy]\),将 \(x\) 移动到 \(qx\),将 \(y\) 移动到 \(qy\) 即可得到答案。
注意:应该先加后减。
时间复杂度
对于右指针 \(y\):
对于同一个块的询问,\(y\) 最多跑 \(n\) 次,每块换 \(1\) 次,最多换 \(O(n)\),总共 \(O(num \times n)\),\(num\) 为块的数量。
对于左指针 \(x\):
对于同一个块中的询问,\(x\) 的单词询问 \(O(size)\),\(size\) 为块长,总时间 \(O(q \times size)\)。
所以总时间复杂度为 \(O(q\times size + num \times n)\)。
奇偶优化
当两个询问的左端点在同一块时,若处于奇数块,则右端点升序,若左端点处于偶数块,则右端点降序。