莫队学习笔记
这是一篇模仿算导风格的学习笔记。
普通莫队
例题:P1494
给定一个长为 \(n\) 的数组 \(a\) 和 \(m\) 个询问(有序数对)\(b_i = (l_i,r_i)\),询问允许离线,对每个询问 \((l, r)\) 求出满足 \(l \le i \lt j \lt r \wedge a_i=a_j\) 的数对 \((i,j)\) 数量.
-
证明:若数 \(x\) 在 \(a\) 数组下标为 \([l, r)\) 的部分中出现次数为 \(c_x\),则询问 \((l, r)\) 的答案为 $$\sum \limits_{c_x \ge 2} \dbinom{c_x}{2}$$
-
若已知 \([l, r)\) 区间的 \(c_x\) 和答案,设计一种方法,在 \(\Theta(1)\) 的时间内得到 \([l, r+1)\),\([l, r-1)\),\([l-1, r)\),\([l+1, r)\) 区间的相关信息。(提示:\(\dbinom{x+1}{2}-\dbinom{x}{2}=x\))
-
对于询问 \(b_i\) 和 \(b_j\),从 \(b_i\) 每次 \(\Theta(1)\) 移动端点到 \(b_j\) 的最坏复杂度是多少?对于 \(m\) 个询问,每次暴力移动的最坏总复杂度是多少?
-
若将 \(m\) 个询问按某个端点(\(l\) 或 \(r\))排序,则最坏总复杂度是多少?
-
设计一种方法,在一个端点有序时使另一个端点相对集中。分析排序后暴力转移端点的时间复杂度。(提示:将这些询问分成 \(\lceil \dfrac{m}{B} \rceil\) 块,使每块内某个端点之差不超过 \(B\))
-
\(B\) 取何值时,总复杂度最小?(提示:\(p,q\) 为正数时 \(\dfrac{p}{x}+qx \ge 2 \sqrt{pq}\),当且仅当 \(\dfrac{p}{x}=qx\) 时取等)
二次离线莫队
例题:P4887
珂朵莉给了你一个长为 \(n\) 的序列 \(a\),每次查询给一个区间 \([l,r]\),查询 \(l \leq i< j \leq r\),且 \(a_i \oplus a_j\) 的二进制表示下有 \(k\) 个 \(1\) 的二元组 \((i,j)\) 的个数。\(\oplus\) 是指按位异或。
-
右端点从 \(r\) 移动到 \(r'(r' \gt r)\) 时,答案的变化量是多少?对左端点和 \(r' \lt r\) 的情况同样分析.
-
把一个点 \(x\) 对 \([l, r)\) 的贡献(一个点在 \([x, x]\),另一个点在 \([l, r)\) 的点对数量)拆成 \(x\) 对 \([0, r)\) 的贡献减 \(x\) 对 \([0, l)\) 的贡献;设计一种预处理的方法,在 \(\Theta(1)\) 时间内计算 \(r\) 对 \([0, r)\) 的贡献.
-
对于 \(r\) 移动中 \(r\) 对 \([0, l)\) 的贡献,将全程总贡献表示为一个区间对另一区间的贡献.
-
对于 \([r, r')\) 对 \([0, l)\) 的贡献,如何暂存这些“离线询问”以便一起回答?(提示:\([r, r')\) 区间可能有 \(O(n^2)\) 个;\([0, l)\) 区间只有 \(\Theta(n)\) 个)
-
设计一种方法回答上一问暂存的“询问”.(提示:考虑从 \([0, l)\) 扩展到 \([0, l+1)\),一共会扩展 \(\Theta(n)\) 次;单点对区间的询问有 \(\Omega(m)\) 个,如何安排转移的询问的复杂度?)