求大佬! 35WA个不停

P4168 [Violet] 蒲公英

command_block @ 2018-10-27 16:39:10

#include<algorithm>
#include<cstdio>
using namespace std;
int n,m,last,l,r,ans,BS,maxx,
    x[50500],t[50500],
    p[205][205],cnt[205][50500],
    o[50500];
    //cnt[i][j] 类似前缀和,在前i个个块中j(离散化后)出现了几次。
    //表示第i个块到第j个块的(最小的)众数。
//快速读入 O(玄学)
inline int read()
{
  int X=0;char ch=0,w=0;
  while(ch<'0'||ch>'9'){w|=ch=='-';ch=getchar();}
  while(ch>47&&ch<58)X=X*10+(ch^48),ch=getchar();
  return w?-X:X;
}
//迭代开方 
int sqrt(int num)
{
  int tmp=100;
  tmp=(num/tmp+tmp)/2;
  tmp=(num/tmp+tmp)/2;
  tmp=(num/tmp+tmp)/2;
  tmp=(num/tmp+tmp)/2;
  tmp=(num/tmp+tmp)/2;
  return tmp;
}
int main()
{
 // freopen("asasa.txt","w",stdout);
 // freopen("ex_4.in","r",stdin);
  n=read();m=read();
 // BS=max(10,min(sqrt(n),n/105));//空间上的问题,至多分成100块 
  BS=1000;
  for (int i=0;i<n;++i)
    {x[i]=read();t[i]=x[i];}
  sort(t,t+n);
  for (int i=0;i<n;++i)
    x[i]=lower_bound(t,t+n,x[i])-t;
  for (int i=0;i<n;++i)cnt[i/BS][x[i]]++;
  for (int i=0;i<=(n-1)/BS;++i)
    for (int j=0;j<n;++j)
      cnt[i][j]+=cnt[i-1][j];
  for (int i=0,tmp;i<=n/BS;++i){
    maxx=-1;tmp=10000000;
    for (int j=i;j<=n/BS;++j){
      for (int k=i*BS;k<j*BS+BS;++k){
        o[x[k]]++;
        if (o[x[k]]>maxx||(o[x[k]]==maxx&&x[k]<tmp)){
          maxx=o[x[k]];
          tmp=x[k];
        }
      }p[i][j]=tmp;
    }for (int j=0;j<n;++j)o[j]=0; 
  }
  //--------输入+离散化+预处理-------- 
  for (int i=0;i<m;i++){
     l=read();r=read();
     l=(l+last-1)%n;
     r=(r+last-1)%n;
     if(l>r)swap(l,r);
    // printf("%d %d ",l,r);*/
     int bl=l!=0?(l-1)/BS+1:0,br=(r+1)/BS-1,tl=bl*BS,tr=br*BS+BS;
     ans=-100;maxx=-1;
     if(br-bl<=2){
       for (int j=l;j<=r;++j)o[x[j]]=0;
       for (int j=l,tmp;j<=r;++j){
         tmp=x[j];
         if (++o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
           {maxx=o[tmp];ans=tmp;}
       }
     }else{
       for (int j=l;j<tl;++j)
         o[x[j]]=cnt[br][x[j]]-cnt[bl-1][x[j]];
       for (int j=tr;j<=r;++j)
         o[x[j]]=cnt[br][x[j]]-cnt[bl-1][x[j]];
       int tmp=p[bl][br];
       o[tmp]=cnt[br][tmp]-cnt[bl-1][tmp];
       if (o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
         {maxx=o[tmp];ans=tmp;}
       for (int j=l;j<tl;++j){
         tmp=x[j];
         if (++o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
           {maxx=o[tmp];ans=tmp;}
       }for (int j=tr;j<=r;++j){           
         tmp=x[j];
         if (++o[tmp]>maxx||(maxx==o[tmp]&&tmp<ans))
           {maxx=o[tmp];ans=tmp;}
       }
     }printf("%d\n",t[ans]);
     last=t[ans];
  }return 0;
}

做法详见题解第一篇。

(分块从0开始)


by xenonex @ 2018-10-27 16:45:11

前排%FFT大佬orz


by Arashi丶 @ 2018-10-27 16:52:31

迭代开方精度不够吧....


by command_block @ 2018-10-27 17:43:18

没用过迭代开方。。。


by command_block @ 2018-11-03 10:54:10

问题已解决


|