求助 区间众数(在线) 分块 WA 0分

P4168 [Violet] 蒲公英

Christophe_ @ 2022-02-03 23:06:45

留下个小 Hack 数据也好哇......小蒟蒻刚学 OI 两个月,在线求调/Hack ; [/可怜]

思路与大部分题解相同,也就是所谓"普通诗乃莫队",预处理次数前缀和和众数。 ,sum 是次数前缀和,mfr 是由块端点构成的区间众数 ;

可是它就是 WA 地一下哭不出来......

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=4e4+2,S=2e2+5;
int n,An,m,a[N],A[N],bl,t,st[S],ed[S],p[N],F[N],sum[S][N],mfr[S][S],K[N],hs[N],mx;
inline int read(){
    register int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)){ if(ch=='-') f=-1;ch=getchar(); }
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return x*f;
}
inline void write(int x){        
    if(x<0){ putchar('-'); x=-x; }      
    if(x>9) write(x/10);     
    putchar(x%10+'0');
}
inline void Discrete(){
    sort(A+1,A+An+1);
    An=unique(A+1,A+An+1)-A;
    for(int i=1;i<=n;++i){
        int tp=lower_bound(A+1,A+An+1,a[i])-A;
        F[tp]=a[i],a[i]=tp;
    }
}
inline void Init(){
    for(int i=1;i<=t;++i){
        mx=0;
        for(int j=1;j<=ed[i];++j) ++sum[i][a[j]];
        for(int r=st[i];r<=n;++r) K[a[r]]=0;
        for(int r=st[i],j=i-1;r<=n;++r){
            ++K[a[r]];
            if(p[r]!=p[r-1]) ++j;
            if(K[a[r]]>K[mx]||(K[a[r]]==K[mx]&&a[r]<mx)) mx=a[r];
            if(p[r]!=p[r+1]) mfr[i][j]=mx;
        }
    }
}
inline void Add(int i){
    ++hs[a[i]];
    if(hs[a[i]]>hs[mx]||(hs[a[i]]==hs[mx]&&a[i]<mx)) mx=a[i];   
}
inline int Query(int l,int r){
    int pl=p[l],pr=p[r];
    if(pl==pr){
        mx=0;
        for(int i=l;i<=r;++i) hs[a[i]]=0;
        for(int i=l;i<=r;++i) Add(i);
    }else{
        mx=mfr[pl+1][pr-1];
        for(int i=l;i<=ed[pl];++i) hs[a[i]]=sum[pr-1][a[i]]-sum[pl][a[i]];
        for(int i=st[pr];i<=r;++i) hs[a[i]]=sum[pr-1][a[i]]-sum[pl][a[i]];
        for(int i=l;i<=ed[pl];++i) Add(i);
        for(int i=st[pr];i<=r;++i) Add(i);
    }
    return mx;
}
int main(){
    An=n=read(),m=read();
    bl=sqrt(n),t=(n-1)/bl+1; 
    for(int i=1;i<=n;++i){
        A[i]=a[i]=read(),p[i]=(i-1)/bl+1;
        if(i<=t) st[i]=(i-1)*bl+1,ed[i]=min(i*bl,n);
    }
    Discrete(),Init();
    int x=0,tl,tr,rl,rr;
    for(int i=1;i<=m;++i){
        tl=read(),tr=read();
        rl=((tl+x-1)%n)+1,rr=((tr+x-1)%n)+1;
        if(rl>rr) swap(rl,rr);
        write(x=F[Query(rl,rr)]),putchar('\n');
    }
    return 0;
}

by Christophe_ @ 2022-02-04 14:23:52

找到了,又是一个细节错误。谢谢各位的帮助!这里献上 AC 代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=4e4+2,S=2e2+5;
int n,An,m,a[N],A[N],bl,t,st[S],ed[S],p[N],F[N],sum[S][N],mfr[S][S],K[N],hs[N],mx;
inline int read(){
    register int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)){ if(ch=='-') f=-1;ch=getchar(); }
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return x*f;
}
inline void write(int x){        
    if(x<0){ putchar('-'); x=-x; }      
    if(x>9) write(x/10);     
    putchar(x%10+'0');
}
inline void Discrete(){
    sort(A+1,A+An+1);
    An=unique(A+1,A+An+1)-A;
    for(int i=1;i<=n;++i){
        int tp=lower_bound(A+1,A+An+1,a[i])-A;
        F[tp]=a[i],a[i]=tp;
    }
}
inline void Init(){
    for(int i=1;i<=t;++i){
        mx=0;
        for(int j=1;j<=ed[i];++j) ++sum[i][a[j]];
        for(int r=st[i];r<=n;++r) K[a[r]]=0;
        for(int r=st[i],j=i-1;r<=n;++r){
            ++K[a[r]];
            if(p[r]!=p[r-1]) ++j;
            if(K[a[r]]>K[mx]||(K[a[r]]==K[mx]&&a[r]<mx)) mx=a[r];
            if(p[r]!=p[r+1]) mfr[i][j]=mx;
        }
    }
}
inline void Add(int i){
    ++hs[a[i]];
    if(hs[a[i]]>hs[mx]||(hs[a[i]]==hs[mx]&&a[i]<mx)) mx=a[i];   
}
inline int Query(int l,int r){
    int pl=p[l],pr=p[r];
    if(pl==pr){
        mx=0;
        for(int i=l;i<=r;++i) hs[a[i]]=0;
        for(int i=l;i<=r;++i) Add(i);
    }else{
        mx=mfr[pl+1][pr-1],hs[mx]=sum[pr-1][mx]-sum[pl][mx];
        for(int i=l;i<=ed[pl];++i) hs[a[i]]=sum[pr-1][a[i]]-sum[pl][a[i]];
        for(int i=st[pr];i<=r;++i) hs[a[i]]=sum[pr-1][a[i]]-sum[pl][a[i]];
        for(int i=l;i<=ed[pl];++i) Add(i);
        for(int i=st[pr];i<=r;++i) Add(i);
    }
    return mx;
}
int main(){
    An=n=read(),m=read();
    bl=sqrt(n),t=(n-1)/bl+1; 
    for(int i=1;i<=n;++i){
        A[i]=a[i]=read(),p[i]=(i-1)/bl+1;
        if(i<=t) st[i]=(i-1)*bl+1,ed[i]=min(i*bl,n);
    }
    Discrete(),Init();
    int x=0,tl,tr,rl,rr;
    for(int i=1;i<=m;++i){
        tl=read(),tr=read();
        rl=((tl+x-1)%n)+1,rr=((tr+x-1)%n)+1;
        if(rl>rr) swap(rl,rr);
        write(x=F[Query(rl,rr)]),putchar('\n');
    }
    return 0;
}

|