蒲公英(bzoj 2724)
Description
Input
修正一下
l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1
Output
Sample Input
6 3
1 2 3 2 1 2
1 5
3 6
1 5
1 2 3 2 1 2
1 5
3 6
1 5
Sample Output
1
2
1
2
1
HINT
修正下:
n <= 40000, m <= 50000
/* 区间的是完整的所有块的众数,和不完整块中出现的数。 先预处理出每块的众数,对于不完整的,直接扫就可以。 那么只要能快速得出一个数在某个区间内出现次数即可。 */ #include<cstdio> #include<iostream> #include<vector> #include<cstring> #include<algorithm> #include<map> #define N 50010 using namespace std; int n,m,val[N],v[N],bl[N],f[510][510],cnt[N],blo=200,id; vector<int> grap[N]; map<int,int> mp; void init(int x){ memset(cnt,0,sizeof(cnt)); int mx=0,ans=0; for(int i=(x-1)*blo+1;i<=n;i++){ cnt[v[i]]++; if(cnt[v[i]]>mx||(cnt[v[i]]==mx&&val[v[i]]<val[ans])) mx=cnt[v[i]],ans=v[i]; f[x][bl[i]]=ans; } } int querysum(int a,int b,int x){ return upper_bound(grap[x].begin(),grap[x].end(),b)-lower_bound(grap[x].begin(),grap[x].end(),a); } int query(int a,int b){ int ans=f[bl[a]+1][bl[b]-1]; int mx=querysum(a,b,ans); for(int i=a;i<=min(bl[a]*blo,b);i++){ int t=querysum(a,b,v[i]); if(t>mx||(t==mx&&val[v[i]]<val[ans])) mx=t,ans=v[i]; } if(bl[a]!=bl[b]){ for(int i=(bl[b]-1)*blo+1;i<=b;i++){ int t=querysum(a,b,v[i]); if(t>mx||(t==mx&&val[v[i]]<val[ans])) mx=t,ans=v[i]; } } return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&v[i]); if(!mp[v[i]]){ mp[v[i]]=++id; val[id]=v[i]; } v[i]=mp[v[i]]; grap[v[i]].push_back(i); } for(int i=1;i<=n;i++)bl[i]=(i-1)/blo+1; for(int i=1;i<=bl[n];i++)init(i); int ans=0; for(int i=1;i<=m;i++){ int a,b;scanf("%d%d",&a,&b); a=(a+ans-1)%n+1;b=(b+ans-1)%n+1; if(a>b)swap(a,b); ans=val[query(a,b)]; printf("%d\n",ans); } return 0; }