回滚莫队
简介
有些题目在区间转移时,可能会出现增加或者删除无法实现的问题。在只有增加不可实现或者只有删除不可实现的时候,就可以使用回滚莫队在 \(O(n \sqrt m)\) 的时间内解决问题。
形式

第一步还是将询问的区间按左端点所在块分组,每组内按右端点排序。 实现时对每组单独处理,以左端点所在块右端点(蓝色虚线)为界线。
- 若左右区间在同一块内,直接暴力计算。
- 在界线右边的区间(灰色线)的右端点单调不降,可以顺着遍历每个位置。
- 在界限左边的区间(绿色线)的左端点无序,每次都需要重新遍历,答案在右边的基础上贡献。
复杂度证明
设分块大小为 \(b\) :
- 对于左右区间在同一块内的询问,每次计算复杂度 \(O(b)\);
- 对于界线左边的区间,每次只会在左端点所在块内计算,复杂度 \(O(b)\);
- 对于界限右边的区间,在每一组内顺着遍历,最多 \(n\) 次,而有 \(\frac{n}{d}\) 组。
总复杂度为 \(O(mb+\frac{n^2}{d})\), \(b=\frac{n}{\sqrt{m}}\) 时最优,为 \(O(n\sqrt{m})\)。
例题
不删除莫队
P5906 【模板】回滚莫队&不删除莫队
给定一个序列,多次询问一段区间 \([l,r]\),求区间中相同的数的最远间隔距离。 序列中两个元素的间隔距离指的是两个元素下标差的绝对值。
对于 \(40\%\) 的数据,满足 \(1\leq a_i \leq 400\), \(1\leq n,m\leq 60000\)。 对于 \(100\%\) 的数据,满足 \(1\leq n,m\leq 2\cdot 10^5\), \(1\leq a_i\leq 2\cdot 10^9\)。
按上述方法实现就行,详细请看代码注释。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
不增加莫队
P4137 Rmq Problem / mex
有一个长度为 \(n\) 的数组 \(\{a_1,a_2,\ldots,a_n\}\)。 \(m\) 次询问,每次询问一个区间内最小没有出现过的自然数。
对于 \(30\%\) 的数据: \(1\leq n,m\leq 1000\)。 对于 \(100\%\) 的数据: \(1\leq n,m\leq 2\times {10}^5\), \(1\leq l\leq r\leq n\), \(0\leq a_i\leq 2\times 10^5\)。
一个集合内最小没有出现过的自然数通常被称为mex。
如果连续插入数,难以维护mex。
容易发现,如果已知mex与一个集合,每次删除其中的数,则mex的变化只会有两种可能:
- 若当前要删的数 \(x\) 只剩一个,并且 \(x<mex\),则删后 \(mex\) 变为 \(x\) ;
- 否则,\(mex\) 不变。
因此也可以用回滚莫队实现,对于每一组内按右端点降序排序,先求出其左侧所在块的左端点到最大右端点的mex,再考虑每次删去一个数时能否更新的mex。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |