[学习笔记]省选算法·莫队
来源:互联网 发布:ios未越狱修改数据 编辑:程序博客网 时间:2024/06/06 03:57
一、开头
神犇EX:你是哪里来的弱菜?你是不是上次NOIP爆0的那个大弱鸡xyz32768?
xyz32768:我就是那个NOIP2017写炸两题的蒟蒻,的确是大弱鸡。
神犇EX:我还听说你连莫队都不会……你恐怕明年NOIP连400都没有了。
xyz32768:莫……莫队?
神犇EX:就是这样:一个
xyz32768:反正我也不懂,算了,我已经做好了NOIP2018爆0的准备了。
二、引入
一个问题:一个
一个想法是线段树,但是也很容易看出,这里线段树上维护的内容没有合并性质,因此线段树不可做。而对于区间的内容没有合并性质的问题,可以用下面介绍的莫队算法解决。
三、莫队算法的条件
1、不包含修改操作。
2、题目允许离线,也就是允许在所有询问全部读入完之后回答所有询问。
3、不同区间的结果可以互相计算得出。怎么理解这个条件呢?
就上面的问题而言,如果上一次已经回答了
四、莫队算法的流程
可以看出,一次移动指针是
莫队算法的主要思想就是这样。同时,莫队算法利用了可以离线的条件,将询问按照合理的顺序进行求解,实现了
首先,将序列分块,即分成
然后,就将询问按照左端点所在的块为第一关键字,右端点的位置为第二关键字进行从小到大排序,这样,就能像上面那样不断移动指针,可以达到
五、复杂度证明
不妨把左端点在同一个块内的询问分成一组。
先考虑右端点的移动次数。由于在同一组询问内的右端点是递增的,所以在同一组内,右端点移动了
再考虑左端点的移动次数。可以看出,在同一组询问内,左端点一次移动的次数为
再加上在跨越两个组时,左端点的移动次数也是
六、BZOJ 1878代码
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 5e4 + 5, M = 1e6 + 5, L = 2e5 + 5;int n, a[N], ans[N], cnt[M];struct cyx { int l, r, bl, id; inline bool operator < (cyx b) const {return bl < b.bl || (bl == b.bl && r < b.r);}} ask[L];int main() { int i, m, S; scanf("%d", &n); S = sqrt(n); for (i = 1; i <= n; i++) scanf("%d", &a[i]); scanf("%d", &m); for (i = 1; i <= m; i++) { scanf("%d%d", &ask[i].l, &ask[i].r); ask[i].id = i; ask[i].bl = (ask[i].l - 1) / S + 1; } sort(ask + 1, ask + m + 1); int tot = 0, sl = 0, sr = 0; for (i = 1; i <= m; i++) { int l = ask[i].l, r = ask[i].r; while (sl < l) if (!--cnt[a[sl++]]) tot--; while (sl > l) if (!cnt[a[--sl]]++) tot++; while (sr < r) if (!cnt[a[++sr]]++) tot++; while (sr > r) if (!--cnt[a[sr--]]) tot--; ans[ask[i].id] = tot; } for (i = 1; i <= m; i++) printf("%d\n", ans[i]); return 0;}
七、题目
1、[BZOJ1878][SDOI2009]HH的项链:
http://www.lydsy.com/JudgeOnline/problem.php?id=1878
2、[BZOJ2038][2009国家集训队]小z的袜子:
http://www.lydsy.com/JudgeOnline/problem.php?id=2038
3、[BZOJ3236][AHOI2013]作业:
http://www.lydsy.com/JudgeOnline/problem.php?id=3236
4、[BZOJ4540][HNOI2016]序列:
http://www.lydsy.com/JudgeOnline/problem.php?id=4540
5、[BZOJ4542][HNOI2016]大数:
http://www.lydsy.com/JudgeOnline/problem.php?id=4542
- [学习笔记]省选算法·莫队
- [学习笔记]省选算法·高斯消元Gauss
- [算法学习笔记]算法基础知识
- 【算法学习笔记】-排序算法
- 【算法学习笔记】贪心算法
- 算法学习笔记--狄克斯特拉算法
- 算法学习笔记--贪婪算法
- MD5算法学习笔记
- 智能算法学习笔记
- 智能算法学习笔记
- 智能算法学习笔记
- 智能算法学习笔记
- CRC32算法学习笔记
- SVM算法学习笔记
- 汉诺塔算法学习笔记
- KMP算法学习笔记
- 智能算法学习笔记
- Prim算法学习笔记
- mysql6.0安装
- 三道典型C语言题(7)
- Java中的锁
- 互联网金融业申请评分卡
- Android手机九宫格密码解锁
- [学习笔记]省选算法·莫队
- 数据结构实验之图论五:从起始点到目标点的最短步数(BFS)
- CF886D Restoration of string
- (作业)使用多线程实现一个大数加程序
- Matlab diag函数功能
- java、exception
- 1043. 输出PATest(20) PAT乙级真题
- vue 项目在另一台电脑各种报错
- halcon的安装