求助,蒟蒻分块WA+TLE10分

P4168 [Violet] 蒲公英

白いバラの夜 @ 2019-01-18 07:49:10

图片在这

https://cdn.luogu.com.cn/upload/pic/48813.png

代码在这

#include<cstdio>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long int ll;
const ll MAX_N=40010;
ll n,m,cnt,a[MAX_N],p[MAX_N],pos[MAX_N],sum,b[MAX_N],t,num[MAX_N],f[210][210],h[210][210],tr[MAX_N],head[MAX_N],tail[MAX_N],q[MAX_N];
inline ll read(){
    ll x=0,f=1;
    char c=getchar();
    while(!isdigit(c)){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(isdigit(c)){
        x=(x<<1)+(x<<3)+c-'0';
        c=getchar();
    }
    return x*f;
}
ll cmp(ll x,ll y){
    return a[x]<a[y];
}
ll cmp1(ll x,ll y){
    return p[x]<p[y]||p[x]==p[y]&&x<y;
}
ll query(ll l,ll r,ll x){
    ll len=lower_bound(q+head[x],q+tail[x]+1,l)-q;
    ll len1=upper_bound(q+head[x],q+tail[x]+1,r)-q;
    return len1-len;
}
ll ask(ll x,ll y){
    ll ansx=0,anss=0,ans=0;
    memset(num,0,sizeof(num));
    if(pos[x]==pos[y]){
        for(int i=x;i<=y;i++){
            num[b[i]]++;
            if(ans<num[b[i]]){
                ans=num[b[i]];
                ansx=a[i];
            }else if(ans==num[b[i]]){
                ansx=min(ansx,a[i]);
            }
        }
    }else{
        int l=pos[x]+1,r=pos[y]-1;
        ans=f[l][r];
        ansx=h[l][r];
        for(int i=x;i<=pos[x]*cnt;i++){
            if(!num[b[i]]){
                num[b[i]]=query(pos[x]+1,pos[y]-1,b[i]);
            }
            num[b[i]]++;
            if(num[b[i]]>ans){
                ans=num[b[i]];
                ansx=a[i];
            }else if(num[b[i]]==ans){
                ansx=min(ansx,a[i]);
            }
        }
        for(int i=(pos[y]-1)*cnt+1;i<=y;i++){
            if(!num[b[i]]){
                num[b[i]]=query(pos[x]+1,pos[y]-1,b[i]);
            }
            num[b[i]]++;
            if(num[b[i]]>ans){
                ans=num[b[i]];
                ansx=a[i];
            }else if(num[b[i]]==ans){
                ansx=min(ansx,a[i]);
            }
        }
    }
    return ansx;
}
int main(){
    n=read(),m=read();
    cnt=sqrt(n);
    for(ll i=1;i<=n;i++){
        a[i]=read();
        p[i]=i;
        pos[i]=(i-1)/cnt+1;
    }
    sort(p+1,p+n+1,cmp);
    for(ll i=1;i<=n;i++){
        if(a[p[i]]!=a[p[i-1]]){
            sum++;
            b[p[i]]=sum;
        }else{
            b[p[i]]=sum;
        }
    }
    if(n%cnt){
        t=n/cnt+1;
    }else{
        t=n/cnt;
    }
    for(ll i=1;i<=t;i++){
        memset(num,0,sizeof(num));
        ll l=(i-1)*cnt+1;
        for(ll j=l;j<=n;j++){
            num[b[j]]++;
            if(!f[i][pos[j]]&&pos[j]!=i){
                f[i][pos[j]]=f[i][pos[j]-1];
                h[i][pos[j]]=h[i][pos[j]-1];
            }
            if(num[b[j]]>f[i][pos[j]]){
                f[i][pos[j]]=num[b[j]];
                h[i][pos[j]]=a[j];
            }
            if(num[b[j]]==f[i][pos[j]]){
                h[i][pos[j]]=min(h[i][pos[j]],a[j]);
            }
        }
    }
    memset(p,0,sizeof(p));
    for(ll i=1;i<=n;i++){
        p[i]=b[i];
        tr[i]=i;
    }
    sort(tr+1,tr+n+1,cmp1);
    for(ll i=1;i<=n;i++){
        if(b[tr[i]]!=b[tr[i-1]]){
            head[b[tr[i]]]=i;
            if(i-1){
                tail[b[tr[i-1]]]=i-1;
            }
        }
    }
    tail[b[tr[n]]]=n;
    for(ll i=1;i<=n;i++){
        q[i]=pos[tr[i]];
    }
    ll k;
    while(m--){
        ll x,y;
        x=read(),y=read();
        x=(x+k-1)%n+1;
        y=(y+k-1)%n+1;
        if(x>y){
            swap(x,y);
        }
        k=ask(x,y);
        printf("%lld\n",k);
    }
    return 0;
}
/*
6 3 
1 2 3 2 1 2 
1 5 
3 6 
1 5

1 
2 
1
*/

by arfa @ 2019-01-18 09:11:57

@白いバラの夜 说说思路


by 白いバラの夜 @ 2019-01-18 09:37:34

@arfa 这道题不就是搞众数吗?


by arfa @ 2019-01-18 10:45:26

@白いバラの夜 所以你是怎么搞的


|