蒟蒻求助,调了一晚上,WA+TLE45。。。

P4168 [Violet] 蒲公英

Dawn_Chase @ 2019-03-28 20:47:35

蒟蒻的码风极丑

希望各位大佬不要吐槽。。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

struct node{
    int x,id,ls;
}a[40010];
int n,m,block,ftrue[40010],ans,maxi,cnt,s[210][210],f[210][210],num[40010];

bool cmp1(node x,node y){
    return x.x<y.x;
}

bool cmp2(node x,node y){
    return x.id<y.id;
}

int main(){
//  freopen("4168.in","r",stdin);
//  freopen("4168.out","w",stdout);
    scanf("%d%d",&n,&m);
    block=sqrt(n);
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i].x);
        a[i].id=i;
    }

    //离散

    sort(a+1,a+n+1,cmp1);
    for (int i=1;i<=n;i++){
        a[i].ls=a[i-1].ls;
        if (a[i].x!=a[i-1].x){
            a[i].ls=++cnt;
            ftrue[a[i].ls]=a[i].x;
        }
    }
    sort(a+1,a+n+1,cmp2);

    //预处理
    //s[i][j]表示前i个块颜色j出现的次数 
    //f[i][j]表示第i个块到第j个块的众数 

    for (int i=1;i<=block;i++){
        for (int j=1;j<=cnt;j++)
            s[i][j]=s[i-1][j];
        for (int j=(i-1)*block+1;j<=i*block&&j<=n;j++){
            s[i][a[j].ls]++;
        }
    }
    for (int i=1;i<=block;i++){
        for (int j=i;j<=block;j++){
            int maxx=0;
            maxi=0;
            for (int k=1;k<=cnt;k++){
                int now=s[j][k]-s[i-1][k];
                if (now>maxx||(now==maxx&&k<maxi))
                    maxx=now,maxi=k;
            }
            f[i][j]=maxi;
        }
    }

    for (int i=1;i<=m;i++){
        int l0,r0;
        scanf("%d%d",&l0,&r0);
        int l=(l0+ans-1)%n+1,r=(r0+ans-1)%n+1;
        if (l>r)
            swap(l,r);
        int bl=(l-1)/block+1,br=(r-1)/block+1;
        if (br-bl>2){
//          maxi=f[bl+1][br-1];
//          ans=s[br-1][maxi]-s[bl][maxi];
            maxi=0;
            ans=0;
            memset(num,0,sizeof(num));
            for (int j=l;j<=bl*block;j++){
                ++num[a[j].ls];
                if (num[a[j].ls]>ans||(num[a[j].ls]==ans&&a[j].ls<maxi)){
                    ans=num[a[j].ls];
                    maxi=a[j].ls;
                }
            }
            for (int j=1;j<=cnt;j++){
                num[j]+=s[br-1][j]-s[bl][j];
                if (num[j]>ans||(num[j]==ans&&j<maxi)){
                    ans=num[j];
                    maxi=j;
                }
            }
            for (int j=(br-1)*block+1;j<=r;j++){
                ++num[a[j].ls];
                if (num[a[j].ls]>ans||(num[a[j].ls]==ans&&a[j].ls<maxi)){
                    ans=num[a[j].ls];
                    maxi=a[j].ls;
                }
            }
            printf("%d\n",ans=ftrue[maxi]);
            continue;
        }
        ans=0;
        maxi=0;
        memset(num,0,sizeof(num));
        for (int j=l;j<=r;j++){
            ++num[a[j].ls];
            if (num[a[j].ls]>ans||(num[a[j].ls]==ans&&a[j].ls<maxi)){
                ans=num[a[j].ls];
                maxi=a[j].ls;
            }   
        }
        printf("%d\n",ans=ftrue[maxi]);
    }

    return 0;
}

by Dawn_Chase @ 2019-03-29 17:32:48

好吧是我傻了。。。 我竟然在统计两边的众数时还加了中间出现的次数。。


上一页 |