对拍拍不出错,0pts求助

P4168 [Violet] 蒲公英

lpx2024 @ 2024-09-23 19:49:41

全是wa和tle,但时间复杂度应该没问题

#include<bits/stdc++.h>
using namespace std;
const int maxN=40010,maxP=500;
struct node{
    int num,id;
} b[maxN];
int a[maxN],c[maxN],d[maxN],g[maxP][maxP],tot[maxN],s[maxP][maxN];
bool cmp(node n1,node n2){
    return n1.num<n2.num;
}
int main(){
    int n,m,tmp=0,l,r,last=0;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        b[i].id=i,b[i].num=a[i];
    }
    sort(b,b+n,cmp);
    for(int i=0;i<n;i++){//离散化 
        if(b[i].num>b[i-1].num || !i) d[++tmp]=b[i].num;
        c[b[i].id]=tmp;
    }
    int p=sqrt(n);
    int q=(n-1)/p; 
    for(int i=0;i<=q;i++){
        for(int j=0;j<p;j++){
            s[i][c[i*p+j]]++;
        }
    }
    for(int i=0;i<=q;i++){
        memset(tot,0,sizeof(tot));
        for(int j=i;j<=q;j++){//从第i块到第j块 
            for(int k=j*p;k<j*p+p && k<n;k++){
                tot[c[k]]++; 
            }
            g[i][j]=g[i][j-1];
            int cnt=tot[g[i][j-1]];
            for(int k=j*p;k<j*p+p && k<n;k++){
                if(tot[c[k]]==cnt && c[k]<g[i][j]) g[i][j]=c[k];
                if(tot[c[k]]>cnt){
                    cnt=tot[c[k]];
                    g[i][j]=c[k];
                }
            }
        }
    } 
    while(m--){
        scanf("%d%d",&l,&r);
        l=(l+last-1)%n,r=(r+last-1)%n;
        if(l>r) swap(l,r);
        int L=l/p,R=r/p,ans=0,cnt=0;
        ans=g[L+1][R-1];
        for(int i=L+1;i<=R-1;i++){
            cnt+=s[i][ans];
        }
        for(int i=l;i<L*p+p;i++){
            int tmpcnt=0;
            for(int j=l;j<L*p+p;j++){
                if(a[j]==a[i]) tmpcnt++;
            }
            for(int j=L+1;j<=R-1;j++){
                cnt+=s[j][c[i]];
            }
            for(int j=R*p;j<=r;j++){
                if(a[j]==a[i]) tmpcnt++;
            }
            if(tmpcnt==cnt){
                if(c[i]<ans) ans=c[i];
            }
            if(tmpcnt>cnt){
                cnt=tmpcnt;
                ans=c[i];
            }
        }
        for(int i=R*p;i<=r;i++){
            int tmpcnt=0;
            for(int j=l;j<L*p+p;j++){
                if(a[j]==a[i]) tmpcnt++;
            }
            for(int j=L+1;j<=R-1;j++){
                cnt+=s[j][c[i]];
            }
            for(int j=R*p;j<=r;j++){
                if(a[j]==a[i]) tmpcnt++;
            }
            if(tmpcnt==cnt){
                if(c[i]<ans) ans=c[i];
            }
            if(tmpcnt>cnt){
                cnt=tmpcnt;
                ans=c[i];
            }
        }
        ans=d[ans];
        last=ans;
        printf("%d\n",last);
    }
    return 0;
}

|