[BZOJ 2002] 弹飞绵羊 LCT

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ 2002] 弹飞绵羊 LCT相关的知识,希望对你有一定的参考价值。

题意

  给定 n 个装置, 每个装置有系数 K[i] .

  在点 i 的绵羊会被弹到 i + K[i] , 如果 i + K[i] > n , 则定义为被弹飞.

  m 次操作, 每次操作是下面的某种:

    ① 更改某个装置的系数 K[x] = y .

    ② 问一只从装置 x 出发的绵羊几次被弹飞.

  n <= 200000 .

 

实现

  1. 不需要换根.

  2.  par[x] 指当前子树中深度最小的点的父亲.

    c[x][0] 的子树指深度比当前点小的一些祖先.

    c[x][1] 的子树指深度比当前点大的一条后继.

    这样理解会比 [ 肤浅地认为是 Splay 的相关信息 ] 要好.

  3. Expose(x)

    Splay(x) , c[x][1] = t, Up(x), t = x, x = par[x] .

        用 2. 解释 c[x][1] = t .

  4. Link(x, y)

    Splay(x), par[x] = y .

  5. Cut(x, y)

    Expose(x), Splay(x), par[c[x][0]] = 0, c[x][0] = 0, Up(x) .

              用 2. 解释后面三个操作.

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 6 inline int rd(void) {
 7     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
 8     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
 9 }
10 
11 const int N = 200005;
12 
13 int n, K[N];
14 int par[N], c[N][2], siz[N];
15 
16 inline void Up(int x) { siz[x] = siz[c[x][0]] + siz[c[x][1]] + 1; }
17 
18 inline bool Root(int x) { return c[par[x]][0] != x && c[par[x]][1] != x; }
19 inline void Rot(int x) {
20     int t = par[x], z = par[t];
21     int L = (c[t][1] == x), R = L^1;
22     
23     if (!Root(t))
24         c[z][c[z][1] == t] = x;
25     par[x] = z;
26     
27     if (c[x][R] > 0)
28         par[c[x][R]] = t;
29     c[t][L] = c[x][R];
30     
31     c[x][R] = t, par[t] = x;
32     Up(t), Up(x);
33 }
34 inline void Splay(int x) {
35     for (; !Root(x); Rot(x)) {
36         int y = par[x], z = par[y];
37         if (!Root(y))
38             (c[y][0] == x) ^ (c[z][0] == y) ? Rot(x) : Rot(y);
39     }
40 }
41 
42 inline void Expose(int x) {
43     for (int t = 0; x > 0; t = x, x = par[x]) {
44         Splay(x);
45         c[x][1] = t, Up(x);
46     }
47 }
48 inline void Link(int x, int y) { Splay(x), par[x] = y; }
49 inline void Cut(int x) { 
50     Expose(x);
51     Splay(x);
52     par[c[x][0]] = 0, c[x][0] = 0, Up(x);
53 }
54 inline int Query(int x) {
55     Expose(x);
56     Splay(x);
57     return siz[x];
58 }
59 
60 int main(void) {
61     #ifndef ONLINE_JUDGE
62         freopen("xsy2531.in", "r", stdin);
63     #endif
64     
65     n = rd();
66     F(i, 1, n) siz[i] = 1;
67     
68     F(i, 1, n) K[i] = rd();
69     F(i, 1, n) if (i + K[i] <= n)
70         Link(i, i + K[i]);
71     
72     int m = rd();
73     F(i, 1, m) {
74         int k = rd();
75         if (k == 1) {
76             int x = rd() + 1;
77             printf("%d\n", Query(x));
78         }
79         else {
80             int x = rd() + 1, y = rd();
81             if (x + K[x] <= n) Cut(x);
82             K[x] = y;
83             if (x + K[x] <= n) Link(x, x + K[x]);
84         }
85     }
86     
87     return 0;
88 }

 

以上是关于[BZOJ 2002] 弹飞绵羊 LCT的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj2002][Hnoi2010]Bounce弹飞绵羊_LCT

bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)

[BZOJ 2002] 弹飞绵羊 LCT

[HNOI2010][BZOJ2002] 弹飞绵羊 - LCT

[bzoj] 2002 弹飞绵羊 || LCT

bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 lct