【题目分析】
区间众数,分块+前缀和
【代码】
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[40010],b[40010],L[40],R[40],buk[40][40][40010],mo[40][40];
int now[40010],lst[40010];
int ans=0,cnt=0,T,tot,l,r;
inline int read()
{
int ret=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
ret*=10;
ret+=ch-'0';
ch=getchar();
}
return ret*f;
}
int main()
{
int n,m; n=read();m=read();
// printf("%d %d\n",n,m);
for (int i=1;i<=n;++i) a[i]=read(),b[i]=a[i];
sort(b+1,b+n+1); cnt=unique(b+1,b+n+1)-b-1;
for (int i=1;i<=n;++i)
a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
T=pow(n+0.1,2.0/3); tot=pow(n,1.0/3);
for (int i=1;i<=tot;++i)
{
L[i]=R[i-1]+1;
R[i]=(i==tot)?n:L[i-1]+T-1;
}
// for (int i=1;i<=tot;++i) printf("%d ",L[i]); puts("");
// for (int i=1;i<=tot;++i) printf("%d ",R[i]); puts("");
for (int i=1;i<=tot;++i)
{
for (int j=L[i];j<=R[i];++j)
buk[i][i][a[j]]++;
for (int j=1;j<=cnt;++j)
if (buk[i][i][j]>buk[i][i][mo[i][i]])
mo[i][j]=j;
}
for (int i=tot;i;--i)
for (int j=i+1;j<=tot;++j)
for (int k=1;k<=cnt;++k)
{
buk[i][j][k]=buk[i][i][k]+buk[i+1][j][k];
if (buk[i][j][k]>buk[i][j][mo[i][j]])
mo[i][j]=k;
}
for (int k=1;k<=m;++k)
{
scanf("%d%d",&l,&r);
l=(l+ans-1)%n+1; r=(r+ans-1)%n+1;
if (l>r) swap(l,r);
// printf("%d %d\n",l,r);
int ll=1,rr=tot;
while (ll<=tot&&L[ll]<l) ll++;
while (rr&&R[rr]>r) rr--;
if (ll>rr)
{
ans=0;
for (int i=l;i<=r;++i)
{
if (lst[a[i]]<k)
{
lst[a[i]]=k;
now[a[i]]=1;
}
else now[a[i]]++;
if (now[a[i]]>now[ans]||
(now[a[i]]==now[ans]&&a[i]<ans))
ans=a[i];
}
ans=b[ans];
printf("%d\n",ans);
continue;
}
ans=mo[ll][rr];
lst[ans]=k;
now[ans]=buk[ll][rr][ans];
for (int i=l;i<L[ll];++i)
{
if (lst[a[i]]<k)
{
lst[a[i]]=k;
now[a[i]]=buk[ll][rr][a[i]]+1;
}
else now[a[i]]++;
if (now[a[i]]>now[ans]||
(now[a[i]]==now[ans]&&a[i]<ans))
ans=a[i];
}
for (int i=R[rr]+1;i<=r;++i)
{
if (lst[a[i]]<k)
{
lst[a[i]]=k;
now[a[i]]=buk[ll][rr][a[i]]+1;
}
else now[a[i]]++;
if (now[a[i]]>now[ans]||
(now[a[i]]==now[ans]&&a[i]<ans))
ans=a[i];
}
ans=b[ans];
printf("%d\n",ans);
}
}