• 数据结构(分块):[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
    ",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
    ",ans);
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    jquery弹出窗口
    js定时器
    jquery树形菜单
    用convert转换参数对比
    jquery常用例子!
    JS总结
    上传简历实现只浏览不下载的效果
    区块链入门(1):搭建(Ubuntu系统)Truffle v3.2.1 开发和测试环境
    URL Routing组件是如何与ASP.NET MVC框架组合起来的
    接单网站收集
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5922884.html
Copyright © 2020-2023  润新知