询问区间最小的众数
先离散化,nsqrt(n)预处理,然后我用vector存了每个值对应的位置,每次二分地找某个值在指定区间当中出现了几次
不开O2疯狂TLE,开了就过了,vector大法好,可以顶平衡树
代码:
#include<bits/stdc++.h> using namespace std; const int maxn=500005; const int inf=0x3f3f3f3f; inline int read(){ char ch=getchar();int s=0,w=1; while(ch<48||ch>57){if(ch=='-')w=-1;ch=getchar();} while(ch>=48&&ch<=57){s=(s<<1)+(s<<3)+ch-48;ch=getchar();} return s*w; } inline void write(int x){ if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+48); } int n,m,lastans=0,l,r; int a[maxn],b[maxn]; int cnt[maxn],ans[1000][1000],num[1000][1000]; int id[maxn],from[1000],to[1000],tot; vector<int> pos[maxn]; void pre(){ tot=sqrt(n); for(int i=1;i<=tot;++i){ from[i]=(i-1)*tot+1; to[i]=i*tot; } if(to[tot]<n) tot++,from[tot]=to[tot-1]+1,to[tot]=n; for(int i=1;i<=tot;++i) for(int j=from[i];j<=to[i];++j) id[j]=i; for(int i=1;i<=tot;++i){ for(int j=i;j<=tot;++j){ num[i][j]=-inf,ans[i][j]=inf; for(int k=from[i];k<=to[j];++k) cnt[a[k]]=0; for(int k=from[i];k<=to[j];++k){ cnt[a[k]]++; if(cnt[a[k]]>num[i][j]){ num[i][j]=cnt[a[k]]; ans[i][j]=a[k]; } else if(cnt[a[k]]==num[i][j]&& a[k]<ans[i][j]) ans[i][j]=a[k]; } } } for(int i=1;i<=n;++i) pos[a[i]].push_back(i); } void solve(){ // l=(l+lastans-1)%n+1; // r=(r+lastans-1)%n+1; l^=lastans; r^=lastans; if(l>r){ int t=l; l=r; r=t; } int tnum=-inf,tans=inf; int pl=id[l],pr=id[r]; if(pl==pr){ for(int i=l;i<=r;++i){ int t1=lower_bound(pos[a[i]].begin(), pos[a[i]].end(),l)-pos[a[i]].begin(); int t2=upper_bound(pos[a[i]].begin(), pos[a[i]].end(),r)-pos[a[i]].begin(); if(t2-t1>tnum){ tnum=t2-t1; tans=a[i]; } else if(t2-t1==tnum&&a[i]<tans) tans=a[i]; } } else{ tnum=num[pl+1][pr-1],tans=ans[pl+1][pr-1]; for(int i=l;i<=to[id[l]];++i){ int t1=lower_bound(pos[a[i]].begin(), pos[a[i]].end(),l)-pos[a[i]].begin(); int t2=upper_bound(pos[a[i]].begin(), pos[a[i]].end(),r)-pos[a[i]].begin(); if(t2-t1>tnum){ tnum=t2-t1; tans=a[i]; } else if(t2-t1==tnum&&a[i]<tans) tans=a[i]; } for(int i=from[id[r]];i<=r;++i){ int t1=lower_bound(pos[a[i]].begin(), pos[a[i]].end(),l)-pos[a[i]].begin(); int t2=upper_bound(pos[a[i]].begin(), pos[a[i]].end(),r)-pos[a[i]].begin(); if(t2-t1>tnum){ tnum=t2-t1; tans=a[i]; } else if(t2-t1==tnum&&a[i]<tans) tans=a[i]; } } // write(b[tans]); // puts(""); // lastans=b[tans]; write(tnum); puts(""); lastans=tnum; } int main(){ n=read(),m=read(); for(int i=1;i<=n;++i) a[i]=read(),b[i]=a[i]; sort(b+1,b+1+n); for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+1+n,a[i])-b; pre(); for(int i=1;i<=m;++i){ l=read(),r=read(); solve(); } return 0; }