BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊

 

2002: [Hnoi2010]Bounce 弹飞绵羊

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 9071  Solved: 4652
[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

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

Sample Output

2
3

HINT

 

Source

 
[Submit][Status][Discuss]

 

将跳转看成边的关系,易知这些转移边形成一棵树。如果以“弹出去”这个状态为根节点,从一个点出发的步数可以转换为深度,或者说是从根节点到这个点的距离。改变一个点的系数,可以视为改变一个点的父节点,但是其子树不会受到影响。显然是个LCT模板题,第一次写还有些许不懂,大体是从这位前辈的blog里学的。

 

  1 VAR 
  2     n : longint;
  3     m : longint;
  4     siz : array[-1..200005] of longint;
  5     fat : array[-1..200005] of longint;
  6     rot : array[-1..200005] of boolean;
  7     son : array[-1..200005,0..2] of longint;
  8 
  9 PROCEDURE update(t : longint);
 10 begin  
 11     siz[t]:=siz[son[t,0]]+siz[son[t,1]]+1;
 12 end;
 13 
 14 PROCEDURE ltrotate(x : longint);
 15 var
 16     y : longint;
 17 begin
 18     y:=son[x,1];
 19     son[x,1]:=son[y,0];
 20     fat[son[x,1]]:=x;
 21     son[y,0]:=x;
 22     if x=son[fat[x],0] then
 23         son[fat[x],0]:=y
 24     else if x=son[fat[x],1] then
 25         son[fat[x],1]:=y;
 26     fat[y]:=fat[x];
 27     fat[x]:=y;
 28     rot[y]:=rot[x] xor rot[y];
 29     rot[x]:=rot[x] xor rot[y];
 30     update(x);
 31     update(y);
 32 end;
 33 
 34 PROCEDURE rtrotate(x : longint);
 35 var 
 36     y : longint;
 37 begin
 38     y:=son[x,0];
 39     son[x,0]:=son[y,1];
 40     fat[son[x,0]]:=x;
 41     son[y,1]:=x;
 42     if x=son[fat[x],0] then
 43         son[fat[x],0]:=y
 44     else if x=son[fat[x],1] then
 45         son[fat[x],1]:=y;
 46     fat[y]:=fat[x];
 47     fat[x]:=y;
 48     rot[y]:=rot[x] xor rot[y];
 49     rot[x]:=rot[x] xor rot[y];
 50     update(x);
 51     update(y);
 52 end;
 53 
 54 PROCEDURE splay(x : longint);
 55 begin
 56     while not rot[x] do
 57         if x=son[fat[x],1] then
 58             ltrotate(fat[x])
 59         else
 60             rtrotate(fat[x]);
 61 end;
 62 
 63 PROCEDURE access(x : longint);
 64 var 
 65     y : longint;
 66 begin
 67     splay(x);
 68     while fat[x]<>0 do
 69     begin
 70         y:=fat[x];
 71         splay(y);
 72         rot[son[y,1]]:=true;
 73         rot[x]:=false;
 74         son[y,1]:=x;
 75         update(y);
 76         splay(x);
 77     end;
 78 end;
 79 
 80 PROCEDURE main;
 81 var
 82     i, x, y, z : longint;
 83 begin
 84     read(n);
 85 
 86     for i:=1 to n do
 87     begin
 88         read(fat[i]);
 89         fat[i]:=fat[i]+i;
 90         if fat[i]>n then
 91             fat[i]:=n+1;
 92     end;
 93 
 94     for i:=1 to n+1 do
 95     begin
 96         siz[i]:=1;
 97         rot[i]:=true;
 98     end;
 99 
100     read(m);
101 
102     for i:=1 to m do
103     begin
104         read(x);
105         if x=1 then
106         begin
107             read(y);
108             inc(y);
109             access(y);
110             writeln(siz[son[y,0]]);
111         end
112         else 
113         begin
114             read(y,z);
115             inc(y);
116             splay(y);
117             fat[son[y,0]]:=fat[y];
118             rot[son[y,0]]:=true;
119             son[y,0]:=0;
120             siz[y]:=siz[son[y,1]]+1;
121             fat[y]:=y+z;
122             if fat[y]>n then
123                 fat[y]:=n+1;
124         end;
125     end;
126 end;
127 
128 BEGIN
129     main;
130 END.

 

  1 #include <bits/stdc++.h>
  2 
  3 #define fread_siz 1024
  4 
  5 inline int get_c(void)
  6 {
  7     static char buf[fread_siz];
  8     static char *head = buf + fread_siz;
  9     static char *tail = buf + fread_siz;
 10 
 11     if (head == tail)
 12         fread(head = buf, 1, fread_siz, stdin);
 13 
 14     return *head++;
 15 }
 16 
 17 inline int get_i(void)
 18 {
 19     register int ret = 0;
 20     register int neg = false;
 21     register int bit = get_c();
 22 
 23     for (; bit < 48; bit = get_c())
 24         if (bit == '-')neg ^= true;
 25 
 26     for (; bit > 47; bit = get_c())
 27         ret = ret * 10 + bit - 48;
 28 
 29     return neg ? -ret : ret;
 30 }
 31 
 32 template <class T>
 33 inline T min(T a, T b)
 34 {
 35     return a < b ? a : b;
 36 }
 37 
 38 const int N = 200005;
 39 
 40 int n, m;
 41 int root[N];
 42 int lson[N];
 43 int rson[N];
 44 int size[N];
 45 int father[N];
 46 
 47 inline void update(int t)
 48 {
 49     size[t] = size[lson[t]] + size[rson[t]] + 1;
 50 }
 51 
 52 inline void rotateLeft(int t)
 53 {
 54     int r = rson[t];
 55     rson[t] = lson[r];
 56     father[rson[t]] = t;
 57     lson[r] = t;
 58     if (t == lson[father[t]])
 59         lson[father[t]] = r;
 60     else if (t == rson[father[t]])
 61         rson[father[t]] = r;
 62     father[r] = father[t];
 63     father[t] = r;
 64     update(t);
 65     update(r);
 66     root[r] ^= root[t];
 67     root[t] ^= root[r];
 68 }
 69 
 70 inline void rotateRight(int t)
 71 {
 72     int l = lson[t];
 73     lson[t] = rson[l];
 74     father[lson[t]] = t;
 75     rson[l] = t;
 76     if (t == lson[father[t]])
 77         lson[father[t]] = l;
 78     else if (t == rson[father[t]])
 79         rson[father[t]] = l;
 80     father[l] = father[t];
 81     father[t] = l;
 82     update(t);
 83     update(l);
 84     root[l] ^= root[t];
 85     root[t] ^= root[l];
 86 }
 87 
 88 inline void splay(int t)
 89 {
 90     while (!root[t])
 91     {
 92         if (t == lson[father[t]])
 93             rotateRight(father[t]);
 94         else
 95             rotateLeft(father[t]);
 96     }
 97 }
 98 
 99 inline void access(int t)
100 {
101     splay(t);
102     
103     while (father[t])
104     {
105         int f = father[t];
106         splay(f);
107         root[rson[f]] = 1;
108         root[t] = 0;
109         rson[f] = t;
110         update(f);
111         splay(t);
112     }
113 }
114 
115 inline void cut(int t)
116 {
117     splay(t);
118     root[lson[t]] = 1;
119     father[lson[t]] = father[t];
120     lson[t] = 0;
121     update(t);
122 }
123 
124 signed main(void)
125 {
126     n = get_i();
127     
128     for (int i = 1; i <= n; ++i)
129         father[i] = min(get_i() + i, n + 1);
130     
131     for (int i = 1; i <= n + 1; ++i)
132         size[i] = root[i] = 1;
133         
134     m = get_i();
135     
136     for (int i = 1; i <= m; ++i)
137     {
138         int x = get_i(), y, z;
139         if (x == 1)
140         {
141             y = get_i() + 1; access(y);
142             printf("%d\n", size[lson[y]]);
143         }
144         else
145         {
146             y = get_i() + 1; z = get_i();
147             cut(y); father[y] = min(n + 1, y + z);
148         }
149     }
150 }

 

 

@Author: YouSiki

posted @ 2016-12-27 15:38  YouSiki  阅读(188)  评论(0编辑  收藏  举报