二话不说,直接看代码.(说不清楚)
方法1:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define g getchar()
using namespace std;
const int N=40010,T=37;
int a[N],b[N],L[T],R[T],pos[N],c[T][T][N],f[T][T][2],now[2];
void add(int x,int y,int num)
{
c[x][y][num]++;
if(c[x][y][num]>now[0]||(c[x][y][num]==now[0]&&num<now[1]))
now[0]=c[x][y][num],now[1]=num;
}
int ask(int l,int r)
{
int p=pos[l],q=pos[r];
int x=0,y=0;
if(p+1<=q-1)
x=p+1,y=q-1;
memcpy(now,f[x][y],sizeof(now));
if(!x)
{
for(int i=l;i<=r;i++)add(x,y,a[i]);
for(int i=l;i<=r;i++)c[x][y][a[i]]--;//还原
}
else
{
for(int i=l;i<=R[p];i++)add(x,y,a[i]);
for(int i=L[q];i<=r;i++)add(x,y,a[i]);
for(int i=l;i<=R[p];i++)c[x][y][a[i]]--;
for(int i=L[q];i<=r;i++)c[x][y][a[i]]--;
}
return b[now[1]];
}
void qr(int &x)
{
char c=g;bool v=(x=0);
while(!( ('0'<=c&&c<='9') || c=='-' ))c=g;
if(c=='-')v=1,c=g;
while('0'<=c&&c<='9')x=x*10+c-'0',c=g;
if(v)x=-x;
}
void write(int x)
{
if(x/10)write(x/10);
putchar(x%10+'0');
}
int main()
{
freopen("2061.in","r",stdin);
freopen("2061.out","w",stdout);
int n,m;qr(n);qr(m);
for(int i=1;i<=n;i++)qr(a[i]),b[i]=a[i];
//离散化
sort(b+1,b+n+1);
int tot=unique(b+1,b+n+1)-(b+1);
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
//分块
int t=pow(1.0*n,1.0/3);//块数
int len=t?n/t:n;
for(int i=1;i<=t;i++)
L[i]=R[i-1]+1,R[i]=i*len;
if(R[t]<n)
{
L[t+1]=R[t]+1;
R[++t]=n;
}
for(int i=1;i<=t;i++)
for(int j=L[i];j<=R[i];j++)
pos[j]=i;
//预处理大块
for(int i=1;i<=t;i++)
for(int j=i;j<=t;j++)
{
memcpy(c[i][j],c[i][j-1],sizeof(c[i][j]));//c[i][j][k]表示第i块~第j块 k出现的次数
memcpy(f[i][j],f[i][j-1],sizeof(f[i][j]));//f[i][j][0]表示第i块~第j块众数的出现个数,f[i][j][1]表示那个众数
for(int k=L[j];k<=R[j];k++)
{
++c[i][j][a[k]];
if(c[i][j][a[k]]>f[i][j][0]||(c[i][j][a[k]]==f[i][j][0]&&a[k]<f[i][j][1]))
f[i][j][0]=c[i][j][a[k]],f[i][j][1]=a[k];
}
}
int x=0;
while(m--)
{
int l,r;qr(l);qr(r);
l=(l+x-1)%n+1;
r=(r+x-1)%n+1;
if(l>r)swap(l,r);
x=ask(l,r);
write(x);puts("");
}
return 0;
}
方法2:
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define g getchar()
using namespace std;
const int N=40010,T=788;
int a[N],b[N],c[N],L[N],R[N],pos[N],f[T][T],ans,cnt;
vector<int>s[N];
bool v[N];
void work(int x,int l,int r)
{
int w=upper_bound(s[x].begin(),s[x].end(),r)-lower_bound(s[x].begin(),s[x].end(),l);
//等价于lower_bound(s[x].begin(),s[x].end(),r+1)-lower_bound(s[x].begin(),s[x].end(),l);
if(w>cnt||(w==cnt&&x<ans))
cnt=w,ans=x;
}
int ask(int l,int r)
{
ans=cnt=0;
memset(v,0,sizeof(v));
int p=pos[l],q=pos[r];
int x=0,y=0;
if(p+1<=q-1)
x=p+1,y=q-1;
if(!x)
{
for(int i=l;i<=r;i++)if(!v[a[i]])
v[a[i]]=1,work(a[i],l,r);
return b[ans];
}
for(int i=l;i<=R[p];i++)if(!v[a[i]])
v[a[i]]=1,work(a[i],l,r);
for(int i=L[q];i<=r;i++)if(!v[a[i]])
v[a[i]]=1,work(a[i],l,r);
if(!v[f[x][y]])
work(f[x][y],l,r);
return b[ans];
}
void qr(int &x)
{
char c=g;bool v=(x=0);
while(!( ('0'<=c&&c<='9') || c=='-' ))c=g;
if(c=='-')v=1,c=g;
while('0'<=c&&c<='9')x=x*10+c-'0',c=g;
if(v)x=-x;
}
void write(int x)
{
if(x/10)write(x/10);
putchar(x%10+'0');
}
int main()
{
freopen("2061.in","r",stdin);
freopen("2061.out","w",stdout);
int n,m;qr(n);qr(m);
for(int i=1;i<=n;i++)qr(a[i]);
memcpy(b,a,sizeof(b));
sort(b+1,b+n+1);
int tot=unique(b+1,b+n+1)-(b+1);
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
s[a[i]].push_back(i);
}
int t=sqrt(log(1.0*n)/log(2.0)*n);
int len=t?n/t:n;
for(int i=1;i<=t;i++)
L[i]=R[i-1]+1,R[i]=i*len;
if(R[t]<n)
{
L[t+1]=R[t]+1;
R[++t]=n;
}
for(int i=1;i<=t;i++)
for(int j=L[i];j<=R[i];j++)
pos[j]=i;
memset(f,0,sizeof(f));
for(int i=1;i<=t;i++)
{
memset(c,0,sizeof(c));
ans=cnt=0;
for(int j=L[i];j<=n;j++)
{
if(++c[a[j]]>cnt||(c[a[j]]==cnt&&a[j]<ans))
cnt=c[a[j]],ans=a[j];
f[i][pos[j]]=ans;
}
}
int x=0;
while(m--)
{
int l,r;qr(l);qr(r);
l=(l+x-1)%n+1;
r=(r+x-1)%n+1;
if(l>r)swap(l,r);
x=ask(l,r);
write(x);puts("");
}
return 0;
}