bzoj 3339 莫队
2017-08-21 10:03
204 查看
题意:
求任意一个区间的SG函数。
想到线段树,但是线段树合并很麻烦。
线段树——分块。
分块的一个应用就是莫队算法。
怎么暴力递推呢?
从一个区间到另一个区间,Ans 取决于 Ans 和 加入和删除的这个数的大小比较。加入一个新数,可能导致Ans 变大,变到哪里去呢? 用一个cnt记录出现数值的个数。
变大到cnt=0的地方。
减去一个数,可能导致Ans 变小。这时就要看cnt 和 大小比较了。
求任意一个区间的SG函数。
想到线段树,但是线段树合并很麻烦。
线段树——分块。
分块的一个应用就是莫队算法。
怎么暴力递推呢?
从一个区间到另一个区间,Ans 取决于 Ans 和 加入和删除的这个数的大小比较。加入一个新数,可能导致Ans 变大,变到哪里去呢? 用一个cnt记录出现数值的个数。
变大到cnt=0的地方。
减去一个数,可能导致Ans 变小。这时就要看cnt 和 大小比较了。
#include <bits/stdc++.h> using namespace std; const int maxn = 200011*41; int N,M; int a[maxn]; int pos[maxn]; int ans[maxn]; int cnt[maxn]; int Ans; struct Node { int l,r; int id; }nodes[maxn]; bool cmp(Node a,Node b) { if(pos[a.l]==pos[b.l]) return a.r < b.r; return pos[a.l] < pos[b.l]; } void add(int x) { cnt[x]++; if(Ans==x) while(cnt[Ans]) Ans++; } void del(int x) { cnt[x]--; if(cnt[x]==0&&x<Ans)Ans=x; } int main(int argc, char const *argv[]) { scanf("%d%d",&N,&M); int sz =ceil(sqrt(1.0*N)); for(int i=1; i <=N; i++) { scanf("%d",&a[i]); pos[i] = (i-1)/sz; } for(int i=1; i <= M; i++) { scanf("%d%d",&nodes[i].l,&nodes[i].r); nodes[i].id = i; } sort(nodes+1,nodes+1+M,cmp); int L = 1,R = 0; Ans = 0; for(int i=1;i<=M;i++) { int id = nodes[i].id; while(R<nodes[i].r)R++,add(a[R]); while(L>nodes[i].l)L--,add(a[L]); while(R>nodes[i].r)del(a[R]),R--; while(L<nodes[i].l)del(a[L]),L++; ans[id]=Ans; } for(int i=1; i <= M; i++) printf("%d\n", ans[i]); return 0; }
相关文章推荐
- BZOJ_3585_mex && BZOJ_3339_Rmq Problem_莫队+分块
- BZOJ 3339/3585 Rmq Problem/mex 莫队算法
- BZOJ 3339: Rmq Problem 莫队算法
- BZOJ 3339: Rmq Problem|莫队算法
- bzoj-2038-莫队
- BZOJ 4810 莫队+bitset
- 【BZOJ2120】数颜色-带修改莫队算法
- 【BZOJ3289】Mato的文件管理-莫队算法+树状数组
- BZOJ 4358 坑 莫队+线段树 死T
- BZOJ 3289 Mato的文件管理 莫队算法+树状数组
- bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队算法
- [bzoj 3809] Gty的二逼妹子序列 莫队+分块
- 【BZOJ】【P3236】【Ahoi2013】【作业】【题解】【莫队】
- [bzoj]2038: [2009国家集训队]美妙的袜子!(莫队)
- [BZOJ3236][Ahoi2013]作业(莫队+分块)
- Bzoj 2120: 数颜色 && 2453: 维护队列 莫队,分块,bitset
- 【bzoj4540】序列 莫队+RMQ
- 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法
- 【bzoj4129】Haruna’s Breakfast 树上莫队+分块
- 【BZOJ4542】大数, 莫队