蒲公英(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

Sample Output

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;
}

 

posted @ 2017-02-22 22:28  karles~  阅读(239)  评论(0编辑  收藏  举报