做了我一上午cccc奇技淫巧来一发
预处理两个块之间的众数,这个预处理是每个延伸一位就算一次,这样就只有根号n个数是有可能更新的,一开始我只会一个个枚举被机房大佬们d飞,预处理每个块每个值的个数。
剩下的就搞搞吧。
细节巨多烦死。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,a[41000]; int lslen,ls[41000]; void LSH() { lslen=0; for(int i=1;i<=n;i++)ls[++lslen]=a[i]; sort(ls+1,ls+lslen+1); lslen=unique(ls+1,ls+lslen+1)-ls-1; for(int i=1;i<=n;i++) a[i]=lower_bound(ls+1,ls+lslen+1,a[i])-ls; } int block,st[41000]; int mx[210][210],cx[210][210],f[210][41000]; int d[41000],ti,tim[41000]; void init_block() { ti=0; for(int i=1;i<=block;i++) { int j=i,zs,cs=0;ti++; for(int k=(i-1)*block+1;k<=n;k++) { if(k!=(i-1)*block+1&&st[k-1]!=st[k]) { mx[i][j]=zs;cx[i][j]=cs; j++; } if(tim[a[k]]!=ti){d[a[k]]=0;tim[a[k]]=ti;} d[a[k]]++; if(cs<d[a[k]]||(cs==d[a[k]]&&zs>=a[k]))zs=a[k],cs=d[a[k]]; } mx[i][j]=zs;cx[i][j]=cs; } memset(f,0,sizeof(f)); int b=1;ti++; for(int i=1;i<=n;i++) { if(i!=1&&st[i-1]!=st[i]) { for(int k=1;k<=n;k++) if(tim[k]==ti)f[b][k]=d[k]; else d[k]=0, tim[k]=ti; b++; } if(tim[a[i]]!=ti){d[a[i]]=0;tim[a[i]]=ti;} d[a[i]]++; } for(int k=1;k<=n;k++) if(tim[k]==ti)f[b][k]=d[k]; else d[k]=0, tim[k]=ti; } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); int Q; scanf("%d%d",&n,&Q); block=floor(sqrt(double(n))); if(block*block<n)block++; for(int i=1;i<=n;i++) scanf("%d",&a[i]), st[i]=(i-1)/block+1; LSH(); init_block(); int l,r,ans=0; while(Q--) { scanf("%d%d",&l,&r); l=(l+ans-1)%n+1,r=(r+ans-1)%n+1; if(l>r)swap(l,r); int ss=0; //for(int i=l;i<=r;i++)printf("%d ",a[i]); if(st[l]==st[r]) { int zs,cs=0;ti++; for(int i=l;i<=r;i++) { if(tim[a[i]]!=ti){d[a[i]]=0;tim[a[i]]=ti;} d[a[i]]++; if(cs<d[a[i]]||(cs==d[a[i]]&&zs>=a[i]))zs=a[i],cs=d[a[i]]; } ans=ls[zs]; printf("%d ",ans); } else { int zs,cs=0; if(st[l]+1<=st[r]-1) { zs=mx[st[l]+1][st[r]-1]; cs=cx[st[l]+1][st[r]-1]; } int li=st[l]*block;ti++; for(int i=l;i<=li;i++) { if(tim[a[i]]!=ti){d[a[i]]=0;tim[a[i]]=ti;} d[a[i]]++; int dd=d[a[i]]+f[st[r]-1][a[i]]-f[st[l]][a[i]]; if(cs<dd||(cs==dd&&zs>=a[i]))zs=a[i],cs=dd; } for(int i=(st[r]-1)*block+1;i<=r;i++) { if(tim[a[i]]!=ti){d[a[i]]=0;tim[a[i]]=ti;} d[a[i]]++; int dd=d[a[i]]+f[st[r]-1][a[i]]-f[st[l]][a[i]]; if(cs<dd||(cs==dd&&zs>=a[i]))zs=a[i],cs=dd; } ans=ls[zs]; printf("%d ",ans); } } return 0; }