蜜汁RE

P4168 [Violet] 蒲公英

chen_qian @ 2020-07-21 20:50:52

#include<bits/stdc++.h>
using namespace std;
const int N=4e4+10;
int a[N],b[N],c[N],k[305][N];
int x,n,m,t,len;
int L[N],R[N],pos[N];
struct node{
    int sum,num;
}pw[305][N];//p[i][j]表示块i到块j的最小众数 
void init(){//离散化+初始化 
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+n+1);
    len=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++)   c[i]=lower_bound(b+1,b+len+1,a[i])-b;
    t=sqrt(n);
    for(int i=1;i<=t;i++){
        L[i]=(i-1)*sqrt(n)+1;
        R[i]=i*sqrt(n);
    }
    for(int i=1;i<=t;i++){
        int s[N];
        memset(s,0,sizeof(s));
        for(int j=i;j<=t;j++){
            for(int k=L[j];k<=R[j];k++){
                s[c[k]]++;
                if(s[c[k]]>pw[i][j].sum||(s[c[k]]==pw[i][j].sum&&pw[i][j].num>a[k])){
                    pw[i][j].sum=s[c[k]];
                    pw[i][j].num=a[k];
                }
            } 
        }
    }
    if(R[t]<n) t++,L[t]=R[t-1]+1,R[t]=n;
    for(int i=1;i<=t;i++){
        for(int j=L[i];j<=R[i];j++){
            pos[j]=i;
            k[i][c[j]]++;
        } 
    }
    for(int i=1;i<=t;i++){
        for(int j=1;j<=len;j++){
            k[i][j]+=k[i-1][j]; 
            //cout<<k[i][j]<<' ';
        }
        //cout<<endl;
    }
    //cout<<"------------------------------"<<endl;
}
int ask(int l,int r){
    int p=pos[l],q=pos[r];
    int ans=-10000,idx=INT_MAX-1,s[N];
    memset(s,0,sizeof(s));
    //cout<<l<<' '<<r<<endl;
    //cout<<p<<' '<<q<<endl;
    if(p==q){
        for(int i=l;i<=r;i++){
            s[c[i]]++;
        }
        for(int i=l;i<=r;i++){
            if(s[c[i]]>ans||(s[c[i]]==ans&&idx>a[i])){
                //cout<<idx<<endl;
                ans=s[c[i]];
                idx=a[i];
            }
        }
    }
    else{
        idx=pw[p+1][q-1].num;
        //cout<<idx<<' '<<ans<<endl;
        for(int j=1;j<=len;j++){
            s[j]+=k[q-1][j]-k[p][j];
        } 
        for(int i=l;i<=R[p];i++)s[c[i]]++;
        for(int i=L[q];i<=r;i++)s[c[i]]++;
        ans=s[idx];
        for(int i=l;i<=R[p];i++){
            if(s[c[i]]>ans||(s[c[i]]==ans&&idx>a[i])){
                //cout<<idx<<endl;
                ans=s[c[i]];
                idx=a[i];
            }
        }
        for(int i=L[q];i<=r;i++){
            if(s[c[i]]>ans||(s[c[i]]==ans&&idx>a[i])){
                //cout<<idx<<endl;
                ans=s[c[i]];
                idx=a[i];
            }
        }
    }
//  cout<<idx<<' '<<ans<<endl;
//  cout<<"-----------------------------"<<endl;
    return idx;
}
int main(){
    init();
    while(m--){
        int l,r;
        scanf("%d%d",&l,&r);
        l=((l+x-1)%n)+1;
        r=((r+x-1)%n)+1;
        x=ask(min(l,r),max(l,r));
        printf("%d\n",x);
    }
    return 0;
}

第一次写分块模版就。。。 求大佬指点(代码本身有问题,但RE确实看不出来)


|