数据结构(分块):[HZOI 2015]easy seq

【题目描述】

给定一个序列,下标从0开始,分别为a0,a1,a2...an1,有m个询问,每次给出lr,求满足ai=ajl<=i<=j<=rji

本题强制在线,lr均进行了加密,解密过程为

l=min((l+ans)modn,(r+ans)modn)

r=max((l+ans)modn,(r+ans)modn)

其中ans为上次答案

【输入格式】

第一行,两个正整数n,m

第二行,n个非负整数a0,a1,a2...an1

以下m行,每行两个数l,r,表示询问

【输出格式】

m行,表示答案

【样例输入】

5 3
0 4 0 0 1
3 2
4 1
0 0

【样例输出】

1
2
0

0<=l,r<n

【来源】

国家集训队2015论文集

  离线预处理+分块,复杂度有保障。

  1 #include <cstdio>
  2 const int N=100001,M=301,B=334;
  3 int n,Q,lmn[N][M],rmx[N][M];
  4 int dp[M][M],a[N],bel[N];
  5 int fst[N][M],lst[N][M];
  6 int st[M],ed[M],tot;
  7 int h[N],vis[N],tim;
  8 char c;int x;
  9 __inline int min(int x,int y){return x>y?y:x;}
 10 __inline int max(int x,int y){return x<y?y:x;}
 11 __inline int Read(){
 12     while(x=getchar()-48,x>9||x<0);
 13     while(c=getchar()-48,c<=9&&c>=0)x=x*10+c;
 14     return x;
 15 }
 16 int main(){
 17     freopen("easy_seq.in","r",stdin);
 18     freopen("easy_seq.out","w",stdout);
 19     scanf("%d%d",&n,&Q);
 20     for(register int i=1;i<=n;i++)a[i]=Read();
 21     for(register int i=1;i<=n;i++)bel[i]=(i-1)/B+1;
 22     for(register int i=1;i<=n;i++)ed[bel[i]]=i;
 23     for(register int i=n;i>=1;i--)st[bel[i]]=i;
 24     
 25     tot=bel[n];
 26     
 27     for(register int i=n;i>=1;i--)fst[a[i]][bel[i]]=i;
 28     for(register int i=1;i<=n;i++)lst[a[i]][bel[i]]=i;
 29     
 30     for(register int i=1;i<=n;i++){
 31         for(register int j=1;j<=bel[i];j++)
 32             lmn[i][j]=fst[a[i]][j];
 33         for(register int j=bel[i];j<=tot;j++)
 34             rmx[i][j]=lst[a[i]][j];
 35     }
 36     
 37     for(register int i=1;i<=n;i++){
 38         for(register int j=bel[i]-1;j>=1;j--)
 39             if(!lmn[i][j])lmn[i][j]=lmn[i][j+1];
 40             else lmn[i][j]=min(lmn[i][j],lmn[i][j+1]); 
 41         for(register int j=bel[i]+1;j<=tot;j++)
 42             rmx[i][j]=max(rmx[i][j],rmx[i][j-1]);
 43     }
 44     
 45     for(register int j=1,i;j<=n;j++){i=bel[j];
 46         dp[i][i]=max(dp[i][i],lst[a[j]][i]-j);
 47         dp[i][i]=max(dp[i][i],j-fst[a[j]][i]);
 48     }
 49     
 50     for(register int k=2;k<=tot;k++)
 51         for(register int i=1,j;(j=i+k-1)<=tot;i++){
 52             dp[i][j]=max(dp[i][j-1],dp[i+1][j]);
 53             for(register int t=st[i];t<=ed[i];t++)
 54             dp[i][j]=max(dp[i][j],rmx[t][j]-t);
 55         }    
 56     int l_,r_,l,r,ans=0;
 57     while(Q--){
 58         l=Read();r=Read();
 59         l_=min((l+ans)%n,(r+ans)%n);
 60         r_=max((l+ans)%n,(r+ans)%n);
 61         l=l_+1;r=r_+1;
 62         
 63         if(bel[l]==bel[r]){
 64             ++tim;ans=0;
 65             for(register int i=l;i<=r;i++){
 66                 if(vis[a[i]]!=tim){
 67                     vis[a[i]]=tim;
 68                     h[a[i]]=i;
 69                 }
 70                 else ans=max(ans,i-h[a[i]]);
 71             }
 72             printf("%d\n",ans);
 73             continue;
 74         }
 75         
 76         if(st[bel[l]]!=l)l_=ed[bel[l]]+1;else l_=l;
 77         if(ed[bel[r]]!=r)r_=st[bel[r]]-1;else r_=r;
 78         
 79         ans=dp[bel[l_]][bel[r_]];++tim;
 80         for(register int i=l;i<l_;i++){
 81             ans=max(ans,rmx[i][bel[r_]]-i);
 82             if(vis[a[i]]!=tim){
 83                 vis[a[i]]=tim;
 84                 h[a[i]]=i;
 85             }
 86             else ans=max(ans,i-h[a[i]]);
 87         }
 88         for(register int i=r_+1;i<=r;i++){
 89             if(!lmn[i][bel[l_]])lmn[i][bel[l_]]=n;
 90             ans=max(ans,i-lmn[i][bel[l_]]);
 91             if(vis[a[i]]!=tim){
 92                 vis[a[i]]=tim;
 93                 h[a[i]]=i;
 94             }
 95             else ans=max(ans,i-h[a[i]]);
 96         }
 97         printf("%d\n",ans);
 98     }
 99     return 0;
100 }

 

posted @ 2016-09-30 10:13  TenderRun  阅读(474)  评论(0编辑  收藏  举报