求助,为什么块长不一样可能会导致WA,是否是我的做法有问题

P4168 [Violet] 蒲公英

lsc72 @ 2024-08-17 13:00:57

#include<bits/stdc++.h>
using namespace std;
int n,m,T,a[40010],ls[40010],p,k,w[2000][2000],ton[40010],l,r,L,R,ans,ll[500],rr[500],o;
vector<int> tp[40010];
inline void read(int &x){
    x=0; char ch=getchar();
    int f=1;
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=-1;
        ch=getchar();
    }
    while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
    x=f*x;
    return;
}
inline void write(int x){
    if (x<0) putchar('-'),x=-x;
    if (x>9) write(x/10);
    putchar(x%10+'0');
    return;
}
int main(){
    read(n);read(m);
    T=sqrt(n*5);
    k=ceil(n*1.0/T);
    for (int i=1;i<=n;i++) read(a[i]),ls[i]=a[i];
    sort(ls+1,ls+n+1);
    int p=unique(ls+1,ls+n+1)-ls-1;
    for (int i=1;i<=n;i++){
        a[i]=lower_bound(ls+1,ls+p+1,a[i])-ls;
        tp[a[i]].push_back(i);
    }
    int pl=1,pr=1;
    for (int i=1;i<=k;++i){
        while (pl<(i-1)*T+1) --ton[a[pl++]];
        ll[i]=(i-1)*T+1;
        rr[i]=min(i*T,n); 
        if (i&1){
            for (int j=i;j<=k;++j){
                int o=0;
                while (pr<min(n,j*T)) ++ton[a[++pr]];
                for (int v=1;v<=p;++v) if (ton[v]>ton[o]) o=v;
                w[i][j]=o;
            }
        }
        else {
            for (int j=k;j>=i;--j){
                int o=0;
                while (pr>min(n,j*T)) --ton[a[pr--]];
                for (int v=1;v<=p;++v) if (ton[v]>ton[o]) o=v;
                w[i][j]=o;
            }
        }
    }
    while (m--){
        read(l); read(r);
        l=(l+ls[ans]-1)%n+1;
        r=(r+ls[ans]-1)%n+1;
        ans=0;int aans=0;
        if (l>r) swap(l,r);
        for (int i=1;i<=p;i++) ton[i]=0;
        L=1; R=k;
        while (ll[L]<l) ++L;
        while (rr[R]>r) --R;
        ++ton[w[L][R]];
        L=ll[L]; R=rr[R];
        int lll=min(r,L),rrr=max(l,R+1);
        for (int i=l;i<lll;++i) ++ton[a[i]];
        for (int i=rrr;i<=r;++i) ++ton[a[i]];
        for (int i=1;i<=p;++i){
            if (ton[i]){
                int u=(upper_bound(tp[i].begin(),tp[i].end(),r)-tp[i].begin())-(lower_bound(tp[i].begin(),tp[i].end(),l)-tp[i].begin());
                if (u>aans){
                    aans=u;
                    ans=i;
                }
            }
        }
        write(ls[ans]);
        putchar('\n');
    }
    return 0;
}

如上是AC代码,块长\sqrt{5n}

块长\sqrt{n}\sqrt{2n}会WA两个点,但速度更快

块长\sqrt{n\log n}不会WA,但慢的要死


by C6H6 @ 2024-08-17 13:36:18

这种时候一般是分块写挂了,你可以块长开2什么的测测小数据


by lsc72 @ 2024-08-17 22:19:51

@C6H6 谢谢大佬,我去试试


|