关于分块的问题

P4168 [Violet] 蒲公英

Refined_heart @ 2021-08-17 21:22:59

蒟蒻本来的代码中块长是 B=sqrt(n) 结果是 WA 85pts, 改成 B=sqrt(n)+100 之后直接就 AC 了,不明白是为啥,请求大佬解答/kel

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int B,bk[N],lastans;
int p[500][N],b[N],blen,bcnt,s[500][500];
int n,m,a[N],num,cnt[N],vis[N];
inline int Min(int x,int y){return x<y?x:y;}
inline int Max(int x,int y){return x>y?x:y;}
inline int getpos(int x){return lower_bound(b+1,b+blen+1,x)-b;}
vector<int>use;
int query(int l,int r){
    int L=bk[l];
    int R=bk[r];
    use.clear();
    if(R-L<=1){
        for(int i=l;i<=r;++i){
            if(!vis[a[i]])use.push_back(a[i]);
            vis[a[i]]++;
        }
        int pos=-1,ct=-1;
        for(auto i:use){
            if(vis[i]>ct){
                ct=vis[i];
                pos=i;
            }
            else if(vis[i]==ct&&i<pos)pos=i;
            vis[i]=0;
        }
        return pos;
    }
    int pos=s[bk[l]+1][bk[r]-1];
    int ct=p[bk[r]-1][pos]-p[bk[l]][pos];
    for(int i=l;i<=Min(bk[l]*B,n);++i){
        if(!vis[a[i]])use.push_back(a[i]);
        vis[a[i]]++;
    }
    for(int i=(bk[r]-1)*B+1;i<=r;++i){
        if(!vis[a[i]])use.push_back(a[i]);
        vis[a[i]]++;
    }
    for(auto i:use){
        if(vis[i]+p[bk[r]-1][i]-p[bk[l]][i]>ct){
            ct=vis[i]+p[bk[r]-1][i]-p[bk[l]][i];
            pos=i;
        }
        else if(vis[i]+p[bk[r]-1][i]-p[bk[l]][i]==ct&&i<pos)pos=i;
        vis[i]=0;
    }
    return pos;
}
void File(){
    freopen("in.txt","r",stdin);
    freopen("My.out","w",stdout);
}
signed main(){
    File();
    scanf("%lld%lld",&n,&m);B=sqrt(n);
    for(int i=1;i<=n;++i)scanf("%lld",&a[i]),b[++bcnt]=a[i];
    sort(b+1,b+bcnt+1);
    blen=unique(b+1,b+bcnt+1)-b-1;
    for(int i=1;i<=n;++i)a[i]=getpos(a[i]);
    for(int i=1;i<=n;++i){
        bk[i]=(i-1)/B+1;
        p[bk[i]][a[i]]++;
    }
    num=(n-1)/B+1;
    for(int i=1;i<=B;++i)
        for(int j=1;j<=blen;++j)
            p[i][j]+=p[i-1][j];
    for(int i=1;i<=num;++i){
        for(int j=1;j<=blen;++j)cnt[j]=0;
        int col=-1,ct=0;
        for(int j=i;j<=num;++j){
            for(int k=(j-1)*B+1;k<=Min(n,j*B);++k){
                cnt[a[k]]++;
                if(cnt[a[k]]>ct){
                    ct=cnt[a[k]];
                    col=a[k];
                }
                else if(cnt[a[k]]==ct&&a[k]<col)col=a[k];
            }
            s[i][j]=col;
        }
    }
    while(m--){
        int l,r;
        scanf("%lld%lld",&l,&r);
        l=(l+lastans-1)%n+1;
        r=(r+lastans-1)%n+1;
        if(l>r)swap(l,r);
        lastans=b[query(l,r)];
        printf("%lld\n",lastans);
    }
    return 0;
}

by 老子是北瓜 @ 2021-08-17 21:28:57

@Refined_heart 因为num似乎求错了


by 老子是北瓜 @ 2021-08-17 21:36:03

呃,我好像搞错了


|