数据结构(块状链表):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 }

 

尽最大的努力,做最好的自己!
原文地址:https://www.cnblogs.com/TenderRun/p/5319276.html