chen_qian @ 2020-07-21 20:50:52
#include<bits/stdc++.h>
using namespace std;
const int N=4e4+10;
int a[N],b[N],c[N],k[305][N];
int x,n,m,t,len;
int L[N],R[N],pos[N];
struct node{
int sum,num;
}pw[305][N];//p[i][j]表示块i到块j的最小众数
void init(){//离散化+初始化
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
len=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++) c[i]=lower_bound(b+1,b+len+1,a[i])-b;
t=sqrt(n);
for(int i=1;i<=t;i++){
L[i]=(i-1)*sqrt(n)+1;
R[i]=i*sqrt(n);
}
for(int i=1;i<=t;i++){
int s[N];
memset(s,0,sizeof(s));
for(int j=i;j<=t;j++){
for(int k=L[j];k<=R[j];k++){
s[c[k]]++;
if(s[c[k]]>pw[i][j].sum||(s[c[k]]==pw[i][j].sum&&pw[i][j].num>a[k])){
pw[i][j].sum=s[c[k]];
pw[i][j].num=a[k];
}
}
}
}
if(R[t]<n) t++,L[t]=R[t-1]+1,R[t]=n;
for(int i=1;i<=t;i++){
for(int j=L[i];j<=R[i];j++){
pos[j]=i;
k[i][c[j]]++;
}
}
for(int i=1;i<=t;i++){
for(int j=1;j<=len;j++){
k[i][j]+=k[i-1][j];
//cout<<k[i][j]<<' ';
}
//cout<<endl;
}
//cout<<"------------------------------"<<endl;
}
int ask(int l,int r){
int p=pos[l],q=pos[r];
int ans=-10000,idx=INT_MAX-1,s[N];
memset(s,0,sizeof(s));
//cout<<l<<' '<<r<<endl;
//cout<<p<<' '<<q<<endl;
if(p==q){
for(int i=l;i<=r;i++){
s[c[i]]++;
}
for(int i=l;i<=r;i++){
if(s[c[i]]>ans||(s[c[i]]==ans&&idx>a[i])){
//cout<<idx<<endl;
ans=s[c[i]];
idx=a[i];
}
}
}
else{
idx=pw[p+1][q-1].num;
//cout<<idx<<' '<<ans<<endl;
for(int j=1;j<=len;j++){
s[j]+=k[q-1][j]-k[p][j];
}
for(int i=l;i<=R[p];i++)s[c[i]]++;
for(int i=L[q];i<=r;i++)s[c[i]]++;
ans=s[idx];
for(int i=l;i<=R[p];i++){
if(s[c[i]]>ans||(s[c[i]]==ans&&idx>a[i])){
//cout<<idx<<endl;
ans=s[c[i]];
idx=a[i];
}
}
for(int i=L[q];i<=r;i++){
if(s[c[i]]>ans||(s[c[i]]==ans&&idx>a[i])){
//cout<<idx<<endl;
ans=s[c[i]];
idx=a[i];
}
}
}
// cout<<idx<<' '<<ans<<endl;
// cout<<"-----------------------------"<<endl;
return idx;
}
int main(){
init();
while(m--){
int l,r;
scanf("%d%d",&l,&r);
l=((l+x-1)%n)+1;
r=((r+x-1)%n)+1;
x=ask(min(l,r),max(l,r));
printf("%d\n",x);
}
return 0;
}
第一次写分块模版就。。。 求大佬指点(代码本身有问题,但RE确实看不出来)