莫队
莫队
莫队主要用来快速处理一个数组中多个区间内不同数字的状态
核心思想
- 分块:把长度为 \(n\) 的数组分为 若干个 长度为\(\sqrt{n}\) 的块
- 离线:对于所有的查询,按照双关键字排序,同一块内按右端点从小到大,否则按块的先后顺序从左到右
定义两个指针 \(l, r\),代表当前维护的区间是 \([l,r]\),对于排好序的查询,用双指针依次扫描查询的区间,时间复杂度 \(O(n\sqrt{n})\)
复杂度分析
假设查询的数量也是 \(n\) * 对于 \(l\) 指针,假设每个块内的查询,\(l\) 都要从左到右或者从右到左,每次的距离是\(\sqrt{n}\),则一共需要跑 \(n\sqrt{n}\)
* 对于 \(r\) 指针,假设每当查询完一个块,\(r\) 指针都在 \(n\),并且要到当前块的最右边,则一共需要跑 \(n\sqrt{n}-\frac{(1+\sqrt{n})*\sqrt{n}}{2}\)
因此总时间复杂度为 \(O(n\sqrt{n})\)
常数优化
每个块内查询的右边界都是升序排序,导致相邻块过渡的时候,右边界相距过远
因此可以奇数块内的查询按右边界升序排序,偶数块内的查询按左边界降序排序,可以达到减小常数的目的
例题
Luogu P2709 小B的询问
题目描述
小 \(B\) 有一个长为 \(n\) 的整数序列 \(a\),值域为 \([1,k]\)。 他一共有 \(m\) 个询问,每个询问给定一个区间 \([l,r]\) 求:\(\sum_{i=1}^{k}c_i^2\)
输入格式
第一行三个整数 \(n,m,k\)。
第二行 \(n\) 个整数,表示小 \(B\) 的序列。
接下来的 \(m\) 行,每行两个整数 \(l,r\)。
输出格式
输出 \(m\) 行,每行一个整数,对应一个询问的答案。
数据范围
\(1 \le n,m,k \le 5 \times 10^4\)
code:
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 勤劳努力的小蜜蜂!