分块0分,有WA有T

P4168 [Violet] 蒲公英

artalter @ 2021-11-13 21:28:22

调了六个小时,累计交了四十多次,结果就写了个这玩意儿出来

#include<bits/stdc++.h>
using namespace std;
int x=0,n,m,cnt,k[205][40205],l,r,l0,r0,N,d[40205],c[40205],t[40205],p[202][202];
map<int,int>a;
map<int,int>b;
int find (int l,int r)
{
    for(int i=l;i<=r;i++)
    {
        t[a[c[i]]]++;
    }
    int maxn=-1;
    for(int i=1;i<=cnt;i++)
    {
        if(t[i]>maxn)
        {
            maxn=t[i];
            x=b[i];
        }else if(t[i]==maxn&&b[i]<x)
        {
            x=b[i];
        }
    }
    return x;
}
int  main()
{
//  freopen("a.txt","r",stdin);
    int n,m;
    scanf("%d%d",&n,&m);
    N=sqrt(n);
    for(int i=1;i<=n+N;i++)
    {
        if(i%N==0)d[i]=i/N;
        else d[i]=i/N+1;
    }
    for(int i=1;i<=n;i++)
    {
    scanf("%d",&c[i]);
        if(!(a.count(c[i])>0))
        {
            a[c[i]]=++cnt;
            b[cnt]=c[i];
        }
        k[d[i]][a[c[i]]]++;
    }
    for(int i=1;i<=d[n];i++)
    {
        memset(t,0,sizeof(t));
        for(int j=i;j<=d[n];j++)
        {
            int maxn=-1,maxx=1e9;
            for(int k=(j-1)*N+1;k<=min(j*N,n);k++)
            {
                t[a[c[k]]]++;
                if(t[a[c[k]]]>maxn)
                {
                    maxn=t[a[c[k]]];
                    maxx=c[k];
                }else if(t[a[c[k]]]==maxn&&c[k]<maxx)
                {
                    maxn=t[a[c[k]]];
                    maxx=c[k];
                }
            }
            p[i][j]=maxx;
        }
    }
    for(int i=1;i<=d[n];i++)
    {
        for(int j=1;j<=cnt;j++)
        {
            k[i][j]+=k[i-1][j];
        }
    }
//  for(int i=1;i<=d[n];i++)
//  {
//      for(int j=1;j<=cnt;j++) 
//      {
//          cout<<k[i][j]<<" "  ;
//      }
//      cout<<endl;
//  }
    while(m --> 0)
    {
        memset(t,0,sizeof(t));
        scanf("%d%d",&l0,&r0);
        l=(l0+x-1)%n+1;
        r=(r0+x-1)%n+1;
        if(l>r)swap(l,r);
        if(d[r]-d[l]<=1)
        {

            x=find(l,r);
            printf("%d\n",x);
        }
        else
        {
            int ll=d[l]*N,rr=d[r]*N-N;
            int maxn=-1;
            for(int i=l;i<=ll;i++)
            {
                t[a[c[i]]]++;
                int s=k[d[r]-1][a[c[i]]]-k[d[l]][a[c[i]]];
                if(t[a[c[i]]]+s>maxn)
                {
                    maxn=t[a[c[i]]]+s;
                    x=c[i];
                }else if(t[a[c[i]]]+s==maxn&&b[i]<x)
                {
                    x=c[i];
                }
            }
            for(int i=rr+1;i<=r;i++)
            {
                t[a[c[i]]]++;
                int s=k[d[r]-1][a[c[i]]]-k[d[l]][a[c[i]]];
                if(t[i]+s>maxn)
                {
                    maxn=t[i]+s;
                    x=c[i];
                }else if(t[i]+s==maxn&&b[i]<x)
                {
                    x=c[i];
                }
            }
            int K=p[d[l]+1][d[r]-1];
            if(t[a[K]]+k[d[r]-1][a[K]]-k[d[l]][a[K]]>maxn)
            {
                maxn=t[a[K]]+k[d[r]-1][a[K]]-k[d[l]][a[K]];
                x=K;
            }else if(t[a[K]]+k[d[r]-1][a[K]]-k[d[l]][a[K]]==maxn&&K<x)
            {
                x=K;
            }
//          for(int i=1;i<=cnt;i++)
//          {
//              int s=k[d[r]-1][i]-k[d[l]][i];
//              if(t[i]+s>maxn)
//              {
//                  maxn=t[i]+s;
//                  x=b[i];
//              }else if(t[i]+s==maxn&&b[i]<x)
//              {
//                  x=b[i];
//              }
//          }
            printf("%d\n",x);
        }
    }
    return 0;
}

by 丙戌年 @ 2021-11-13 21:59:02

%%%% dalao为什么不考虑考虑线段树呢¿¿


by LordLaffey @ 2021-11-13 22:21:37

@artalter dalao珂以尻虑尻虑线段树欧~~


by 阿丑 @ 2021-11-17 13:46:57

@artalter 每次询问都清空一次 t 数组会 T 吧


by 阿丑 @ 2021-11-17 13:52:49

for(int i=rr+1;i<=r;i++)
{
    t[a[c[i]]]++;
    int s=k[d[r]-1][a[c[i]]]-k[d[l]][a[c[i]]];
    if(t[i]+s>maxn)
    {
        maxn=t[i]+s;
        x=c[i];
    }else if(t[i]+s==maxn&&b[i]<x)
    {
        x=c[i];
    }
}

这里写错了(


|