bzoj3585: mex
传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3585
思路:又是一道莫队+分块。
对权值分块,大于n的直接不用管。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> const int maxn=200010,maxb=450; using namespace std; struct que{int l,r,id;}q[maxn]; int n,m,sz,cnt,a[maxn],s[maxn],bel[maxn],l[maxb],r[maxb],bloans[maxn],ans[maxn]; bool cmp(que a,que b){return bel[a.l]==bel[b.l]?a.r<b.r:bel[a.l]<bel[b.l];} void add(int x){ if (x>n) return; if (!s[x]++) bloans[bel[x]]++; } void del(int x){ if (x>n) return; if (!--s[x]) bloans[bel[x]]--; } int query(){ int i;if (!s[0]) return 0; for (i=1;i<=cnt;i++) if (bloans[i]!=r[i]-l[i]+1) break; for (int j=l[i];j<=r[i];j++) if (!s[j]) return j; } void work(){ for (int i=1,l=1,r=0;i<=m;i++){ for (;r<q[i].r;r++) add(a[r+1]); for (;r>q[i].r;r--) del(a[r]); for (;l<q[i].l;l++) del(a[l]); for (;l>q[i].l;l--) add(a[l-1]); ans[q[i].id]=query(); } for (int i=1;i<=m;i++) printf("%d\n",ans[i]); } int main(){ scanf("%d%d",&n,&m),sz=sqrt(n),cnt=n/sz+(n%sz>0); for (int i=1;i<=n;i++) bel[i]=(i-1)/sz+1; for (int i=1;i<=n;i++){r[bel[i]]=i;if (!l[bel[i]]) l[bel[i]]=i;} for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]; for (int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+1+m,cmp),work(); return 0; }