题目:蒲公英
思路:
分块。
把所有数分成
n
\sqrt{n}
n个块,在每个块里分别求解。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 40000
#define maxq 200
#define read(x) scanf("%d",&x)
int n,m;
int a[maxn+5];
map<int,int> mp;
int dic[maxn+5],cnt;
int cq,sq;
int p[maxq+5][maxq+5];
int s[maxq+5][maxn+5];
int vis[maxn+5];
int main() {
read(n),read(m);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) mp[a[i]]++;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it) {
mp[it->first]=++cnt;
dic[cnt]=it->first;
}
for(int i=1;i<=n;i++) a[i]=mp[a[i]];
sq=sqrt(n),cq=n/sq+(n%sq!=0);
for(int i=1;i<=cq;i++) {
for(int j=1;j<=cnt;j++) s[i][j]=s[i-1][j];
for(int j=(i-1)*sq+1;j<=min(n,i*sq);j++) {
s[i][a[j]]++;
}
}
for(int i=1;i<=cq;i++) {
for(int k=(i-1)*sq+1;k<=n;k++) {
int j=1+(k-1)/sq;
if(k%sq==1) p[i][j]=p[i][j-1];
vis[a[k]]++;
if(vis[a[k]]>vis[p[i][j]]||(vis[a[k]]==vis[p[i][j]]&&a[k]<p[i][j])) p[i][j]=a[k];
}
memset(vis,0,sizeof(vis));
}
int lst=0;
for(int i=1;i<=m;i++) {
int x,y,l,r;
read(x),read(y);
x=(lst+x-1)%n+1,y=(lst+y-1)%n+1;
if(x>y) swap(x,y);
l=x-x%sq+sq+1;
r=y-y%sq;
int L=l/sq+1,R=r/sq;
int t=p[L][R];
if(L>R) {
int P=0;
for(int j=x;j<=y;j++) {
vis[a[j]]++;
if(vis[a[j]]>vis[P]||(a[j]<P&&vis[a[j]]==vis[P])) P=a[j];
}
memset(vis,0,sizeof(vis));
printf("%d\n",lst=dic[P]);continue;
}
for(int j=x;j<l;j++) {
s[R][a[j]]++;
if(s[R][a[j]]-s[L-1][a[j]]>s[R][p[L][R]]-s[L-1][p[L][R]]||(s[R][a[j]]-s[L-1][a[j]]==s[R][p[L][R]]-s[L-1][p[L][R]]&&a[j]<p[L][R])) p[L][R]=a[j];
}
for(int j=r+1;j<=y;j++) {
s[R][a[j]]++;
if(s[R][a[j]]-s[L-1][a[j]]>s[R][p[L][R]]-s[L-1][p[L][R]]||(s[R][a[j]]-s[L-1][a[j]]==s[R][p[L][R]]-s[L-1][p[L][R]]&&a[j]<p[L][R])) p[L][R]=a[j];
}
printf("%d\n",lst=dic[p[L][R]]);
for(int j=x;j<l;j++) s[R][a[j]]--;
for(int j=r+1;j<=y;j++) s[R][a[j]]--;
p[L][R]=t;
}
return 0;
}