[bzoj2724] [Violet 6]蒲公英
离散化+分块大法。
在线询问区间众数。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define ll long long 7 #define us unsigned short 8 using namespace std; 9 const int maxn=40233,knum=233; 10 struct zs{int v,id;}a[maxn]; 11 us pre[knum][maxn],ans[knum][maxn],sum[knum][maxn]; 12 us num[maxn]; 13 int l[knum],r[knum],bel[maxn],kuai; 14 int b[maxn],mp[maxn]; 15 int i,j,k,n,m,cnt; 16 17 int ra;char rx; 18 inline int read(){ 19 rx=getchar(),ra=0; 20 while(rx<'0'||rx>'9')rx=getchar(); 21 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 22 } 23 inline int query(int L,int R){ 24 int j,idl=bel[L],idr=bel[R],mx=0,v=0,tmpmx,tmpv;register int i; 25 if(L==l[idl])return b[ans[idl][R]]; 26 if(idl==idr){ 27 for(i=L;i<=R;i++) 28 if(++num[mp[i]]==mx?mp[i]<v:num[mp[i]]>mx)mx=num[mp[i]],v=mp[i]; 29 for(i=L;i<=R;i++)num[mp[i]]=0; 30 return b[v]; 31 } 32 tmpmx=sum[idl+1][R],tmpv=ans[idl+1][R]; 33 for(i=L;i<=r[idl];i++)num[mp[i]]++;tmpmx+=num[tmpv]; 34 for(i=l[idr];i<=R;i++)num[mp[i]]++; 35 for(i=L;i<=r[idl];i++){ 36 j=num[mp[i]]+pre[idr-1][mp[i]]-pre[idl][mp[i]]; 37 if(j==tmpmx?mp[i]<tmpv:j>tmpmx)tmpmx=j,tmpv=mp[i]; 38 } 39 for(i=L;i<=r[idl];i++)num[mp[i]]=0; 40 for(i=l[idr];i<=R;i++)num[mp[i]]=0; 41 return b[tmpv]; 42 } 43 bool cmp(zs a,zs b){return a.v<b.v;} 44 int main(){ 45 n=read(),m=read(),kuai=max(5,(int)sqrt(n)-20); 46 for(i=1;i<=n;i++)a[i].v=read(),a[i].id=i,bel[i]=(i+kuai-1)/kuai; 47 sort(a+1,a+1+n,cmp); 48 for(i=1;i<=n;mp[a[i].id]=cnt,i++) 49 if(a[i].v!=a[i-1].v)b[++cnt]=a[i].v; 50 for(i=1;i<=bel[n];i++)l[i]=(i-1)*kuai+1,r[i]=i==bel[n]?n:(l[i]+kuai-1); 51 52 for(i=1;i<=bel[n];i++){ 53 int mx=0,v=0; 54 for(j=l[i];j<=n;j++){ 55 if(++num[mp[j]]==mx?mp[j]<v:num[mp[j]]>mx)mx=num[mp[j]],v=mp[j]; 56 ans[i][j]=v,sum[i][j]=mx; 57 } 58 memset(num,0,(cnt+1)<<1); 59 } 60 61 for(i=1;i<=n;i++){ 62 num[mp[i]]++; 63 if(i==r[bel[i]])memcpy(pre[bel[i]],num,(cnt+1)<<1); 64 }memset(num,0,(cnt+1)<<1); 65 int last=0; 66 while(m--){ 67 i=(read()+last-1)%n+1,j=(read()+last-1)%n+1; 68 if(i>j)swap(i,j); 69 printf("%d\n",last=query(i,j)); 70 } 71 }