有一个长度为n的数组\({a_1,a_2,…,a_n}\)。\(m\)次询问,每次询问一个区间内最小没有出现过的自然数。
第一行\(n\),\(m\)。
第二行为\(n\)个数。
从第三行开始,每行一个询问\(l\),\(r\)。
一行一个数,表示每个询问的答案。
输入 #1
5 5
2 1 0 2 1
3 3
2 3
2 4
1 2
3 5
输出 #1
1
2
3
0
3
对于30%的数据:1<=n,m<=1000
对于100%的数据:1<=n,m<=200000,0<=ai<=10^9,1<=l<=r<=n
难点在\(add\)函数上。给我的教训是,变量名最好要有实际意义,不要盲目追求短小,否则巨难debug。
↓拿到了一个新的元素,检查是否是刚刚加入的。如果是,并且这个数是原来区间的\(mex\),那么就暴力更新新的 \(mex\)即可。
inline void add(int pos) { cnt[a[pos]]++; if(cnt[a[pos]]==1&&now==a[pos]) { int tmp=a[pos]; while(cnt[tmp]!=0)tmp++; now=tmp; return; } }
开\(o2\)会WA两个点,我猜是\(cmp\)函数的锅:
return (belong[i.l] ^ belong[j.l]) ? (belong[i.l]<belong[j.l]):((belong[i.l]&1)? i.r<j.r:i.r>j.r);
这个玄学优化可能是厌氧的
code:
#include<bits/stdc++.h> using namespace std; const int M=200010; int n,m,a[M],belong[M],size,bnum,ans[M],now; int L=1,R=0,ql,qr; //map<int,int> cnt; int cnt[M]; inline int read() { char c=getchar();int x=0; for(;!isdigit(c);c=getchar()); for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x; } void pr(int x) { if(x/10) pr(x/10); putchar(x%10+'0'); } struct query { int l,r,id; }q[M]; bool cmp(query i,query j) { return (belong[i.l] ^ belong[j.l]) ? (belong[i.l]<belong[j.l]):((belong[i.l]&1)? i.r<j.r:i.r>j.r); //return (belong[i.l]==belong[j.l]) ? i.r<j.r : i.l<j.l; } inline void add(int pos) { //if((!(1+cnt[a[x]]))&&a[x]<now)now=a[x]; cnt[a[pos]]++; if(cnt[a[pos]]==1&&now==a[pos]) { // cnt[a[x]]++; int tmp=a[pos]; while(cnt[tmp]!=0)tmp++; now=tmp; return; // while(++tmp) // { // if(cnt[tmp]==0) // { // now=tmp; // return ; // } // } } } inline void del(int pos) { if((!(--cnt[a[pos]]))&&a[pos]<now)now=a[pos]; } int main() { n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=m;i++) { q[i].id=i; q[i].l=read(); q[i].r=read(); } size=sqrt(n); bnum= ceil((double)n/size); for(int i=1;i<=bnum;i++) for(int j=(i-1)*size+1;j<=i*size;j++) belong[j]=i; // for(int i=1;i<=n;i++)cout<<belong[i]<<' '; sort(q+1,q+m+1,cmp); for(int i=1;i<=m;i++) { ql=q[i].l;qr=q[i].r; while(L<ql) del(L++); while(L>ql) add(--L); while(R>qr) del(R--); while(R<qr) add(++R); ans[q[i].id]=now; } for(int i=1;i<=m;i++)pr(ans[i]),putchar('\n'); return 0; }
来源:博客园
作者:Libeccio
链接:https://www.cnblogs.com/kion/p/11817121.html