• 数据结构(块状链表):COGS 1689. [HNOI2010]Bounce 弹飞绵羊



      时间限制:1 s   内存限制:259 MB

    【题目描述】

      某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿 着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置, 则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何 时候弹力系数均为正整数。

    【输入格式】

      第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m, 接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成 k。对于10%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    【输出格式】

      对于每个i=1的情况,你都要输出一个需要的步数,占一行。

    【样例输入】

    4                              
    1 2 1 1						   
    3
    1 1
    2 1 1
    1 1
      

    【样例输出】

    2
    3
      
      由于修改操作很多,可以将复杂度摊给询问操作。
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <cmath>
     5 using namespace std;
     6 const int maxn=200010;
     7 int a[maxn],bel[maxn],sum[maxn],to[maxn];
     8 int n,m,K,Q;
     9 int Query(int x){
    10     int ret=0;
    11     while(x!=-1){
    12         ret+=sum[x];
    13         x=to[x];
    14     }
    15     return ret;
    16 }
    17 int main(){
    18     freopen("bzoj_2002.in","r",stdin);
    19     freopen("bzoj_2002.out","w",stdout);
    20     scanf("%d",&n);
    21     m=sqrt(n+0.5);
    22     for(int i=1;i<=n;i++){
    23         if((i-1)%m==0)K++;
    24         bel[i]=K;
    25         scanf("%d",&a[i]);
    26     }
    27     for(int i=n;i>=1;i--){
    28         if(i+a[i]>n){
    29             to[i]=-1;
    30             sum[i]=1;
    31         }
    32         else{
    33             if(bel[i]==bel[i+a[i]]){
    34                 to[i]=to[i+a[i]];
    35                 sum[i]=sum[i+a[i]]+1;
    36             }
    37             else{
    38                 to[i]=i+a[i];
    39                 sum[i]=1;
    40             }
    41         }
    42     }
    43     scanf("%d",&Q);
    44     while(Q--){
    45         int op,x,y;
    46         scanf("%d",&op);
    47         if(op==1){
    48             scanf("%d",&x);x++;
    49             printf("%d
    ",Query(x));
    50         }
    51         else{
    52             scanf("%d%d",&x,&y);x++;
    53             a[x]=y;
    54             if(x+y>n){
    55                 sum[x]=1;
    56                 to[x]=-1;
    57             }
    58             else{
    59                 if(bel[x]==bel[x+y]){
    60                     to[x]=to[x+y];
    61                     sum[x]=sum[x+y]+1;
    62                 }
    63                 else{
    64                     to[x]=x+y;
    65                     sum[x]=1;
    66                 }
    67             }
    68             for(int p=x-1;bel[p]==bel[x];p--)
    69                 if(bel[p]==bel[p+a[p]])
    70                     sum[p]=sum[p+a[p]]+1,to[p]=to[p+a[p]];
    71         }
    72     }
    73     return 0;
    74 }

     

    尽最大的努力,做最好的自己!
  • 相关阅读:
    前端资源
    WCF常见异常-The maximum string content length quota (8192) has been exceeded while reading XML data
    Asp.Net MVC路由调试工具-RouteDebugger
    Java中String 的equals 和==详解
    记一次高级java工程师职位的面试
    java中Class对象详解和类名.class, class.forName(), getClass()区别
    2014读书计划
    Javascript quiz
    CSS3 Flexbox布局那些事
    前端开发中的图片优化
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5319276.html
Copyright © 2020-2023  润新知