• BZOJ4095 : [Usaco2013 Dec]The Bessie Shuffle


    首先将排列和整个序列以及询问都反过来,问题变成给定一个位置$x$,问它经过若干轮置换后会到达哪个位置。

    每次置换之后窗口都会往右滑动一个,因此其实真实置换是$p[i]-1$。

    对于每个询问,求出轮数,倍增找到最终位置,注意当中途走到$0$时,说明离开了窗口,应及时终止。

    时间复杂度$O((m+q)log n)$。

    #include<cstdio>
    const int N=100010,M=30;
    int n,m,q,i,j,x,r,k,a[M][N];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    int main(){
      read(n),read(m),read(q);
      for(i=m;i;i--)read(x),a[0][m-x+1]=i-1;
      for(i=1;i<M;i++)for(j=1;j<=m;j++)a[i][j]=a[i-1][a[i-1][j]];
      while(q--){
        read(x);
        if(x<m)r=m;else r=x,x=m;
        k=n-r+1;
        for(i=M-1;~i;i--)if((1<<i)<=k&&a[i][x])x=a[i][x],k-=1<<i,r+=1<<i;
        if(k)x=a[0][x],r++;
        printf("%d
    ",n-(r-m+x)+1);
      }
      return 0;
    }
    

      

  • 相关阅读:
    2018.7.12训练赛 -K
    winter 2018 02 01 关于模运算的一道题
    debug(实验)
    problem-1003(恢复一下)
    hd acm1466
    hd acm2045
    hd acm 1297
    hd acm1005
    hd acm1425
    概率趣题:三个犯人
  • 原文地址:https://www.cnblogs.com/clrs97/p/7468655.html
Copyright © 2020-2023  润新知