莫队算法
来源:互联网 发布:淘宝项链店铺 编辑:程序博客网 时间:2024/05/14 23:58
满足以下两个条件的即可使用莫队算法:
1. 只有查询没有修改
2. 可由[l, r] O(1)或O(lgn) 推出[l + 1, r], [l - 1, r], [l, r - 1], [l, r + 1]
复杂度即为O(n ^ 1.5)或O(n ^ 1.5 * lgn)
莫队算法是将询问按左端点所在块作为第一关键字,右端点作为第二关键字排序。
莫队算法非常容易实现,只需排好序顺着计算就好了。关键是复杂度证明。
先大致说下实现过程。
例题: bzoj2038 [2009国家集训队] 小z的袜子(house)
题目大意:
长度为n的序列代表n只袜子,每只袜子有颜色ci(不分左右,型号,只关注颜色),m个询问,询问区间内抽到一双相同颜色袜子的概率。
题解:
无查询;记录区间内抽到一双相同颜色袜子的排列数,如果知道[l, r]的答案,
可以通过nowans -= cnt[r + 1] * (cnt[r + 1] - 1);++cnt[r + 1]; nowans += cnt[r + 1] * (cnt[r + 1] - 1); O(1)求得[l, r + 1]的答案。[l + 1, r], [l - 1, r], [l, r - 1]同理。其中cnt[x]表示当前区间内颜色x的个数。
故可使用莫队。
假设一开始我们找到一个区间的答案(比如[1, 0])。对于m个询问,我们按莫队算法描述的顺序排序,按照这个顺序依次用第i个答案推出第i+1个答案。每一步操作数都是| l' - l | + | r' - r |。
主要代码:
void updata(int x, int y) { now -= (ll)cnt[x] * (cnt[x] - 1); cnt[x] += y; now += (ll)cnt[x] * (cnt[x] - 1);}
for (int i = 0, l = 1, r = 0; i < m; ++i) { while (r < q[i].r) updata(c[++r], 1); while (r > q[i].r) updata(c[r--], -1); while (l > q[i].l) updata(c[--l], 1); while (l < q[i].l) updata(c[l++], -1); if (now == 0) { a[q[i].id] = 0; b[q[i].id] = 1; } else { a[q[i].id] = now; b[q[i].id] = (ll)(q[i].r - q[i].l + 1) * (q[i].r - q[i].l); ll tmp = __gcd(a[q[i].id], b[q[i].id]); a[q[i].id] /= tmp; b[q[i].id] /= tmp; }}下面给出粗略证明。由于n, m同一级别,所以计算复杂度时都用n来表示。
总共分成了n ^ 0.5块,我们不妨假设这n ^ 0.5块每块的第一个都是暴力算出来的。暴力算一个区间[l, r]是O(n),总共是O(n ^ 1.5)。
然后在每块内分别考虑左端点和右端点。
左端点:
同一块之间左端点相差不超过n ^ 0.5,所以每次最多移动n ^ 0.5次,总共需计算n个询问,复杂度是O(n ^ 1.5)。
右端点:
在同一块里,右端点递增,最多移动n次,总共有n ^ 0.5块, 所以移动n ^ 1.5次。复杂度也是O(n ^ 1.5)。
综上,总复杂度O(n ^ 1.5)。
练习题:hdu5145 NPY and girls
- 关于分块算法and莫队算法
- {莫队算法}
- bzoj2038莫队算法
- 莫队算法
- hdu4638莫队算法
- 树上莫队算法
- 莫队算法
- 莫队算法小结
- BZOJ3781【莫队算法】
- BZOJ2038【莫队算法】
- 莫队算法小结
- 莫队算法
- 莫队算法模板
- 莫队算法小结
- 莫队算法
- 莫队算法
- 莫队算法笔记
- 莫队算法
- Codeforces Round #283 div2 C (div1 A) 496C Removing Columns
- WPF书写数据库语句要仔细啊
- 见面之后的感想
- hadoop namenode启动过程详细剖析及瓶颈分析
- codeforces div2 496
- 莫队算法
- 安卓根据号码获取联系人姓名和头像
- Resetting Password for Ubuntu
- 循环素数
- Codeforces 496D
- excel如何快速自动填充空白单元格上一行的内容
- php解析 gzip压缩 chunked快传输
- php数据采集
- redis 持久化(persistence)