lct入门题?只需要Link Cut,不需要换根和维护其他标记
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 200000 + 10; 6 7 int ch[N][2], p[N], sz[N], tl[N]; 8 9 int n, m; 10 11 bool isroot(int x) { 12 return ch[p[x]][0] != x && ch[p[x]][1] != x; 13 } 14 #define l ch[x][0] 15 #define r ch[x][1] 16 void update(int x) { 17 assert(x != 0); 18 sz[x] = sz[l] + sz[r] + 1; 19 } 20 #undef l 21 #undef r 22 23 void rotate(int x) { 24 int y = p[x], z = p[y]; 25 int l = ch[y][1] == x, r = l ^ 1; 26 if(!isroot(y)) ch[z][ch[z][1] == y] = x; 27 p[ch[x][r]] = y; 28 p[y] = x; 29 p[x] = z; 30 31 ch[y][l] = ch[x][r]; 32 ch[x][r] = y; 33 34 update(y), update(x); 35 } 36 37 void splay(int x) { 38 while(!isroot(x)) { 39 int y = p[x], z = p[y]; 40 if(!isroot(y)) { 41 if((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x); 42 else rotate(y); 43 } 44 rotate(x); 45 } 46 } 47 48 void access(int x) { 49 for(int t = 0; x ; t = x, x = p[x]) { 50 splay(x), ch[x][1] = t, update(x); 51 } 52 } 53 54 int getroot(int x) { 55 for(access(x), splay(x); ch[x][0]; x = ch[x][0]); 56 return splay(x), x; 57 } 58 59 void Cut(int x) { 60 access(x), splay(x); 61 p[ch[x][0]] = 0, ch[x][0] = 0; 62 update(x); 63 } 64 65 void Link(int x, int y) { 66 Cut(x), p[x] = y; 67 } 68 69 int main() { 70 #ifdef DEBUG 71 freopen("in.txt", "r", stdin); 72 #endif 73 74 int n; scanf("%d", &n); 75 for(int i = 1; i <= n; i++) { 76 sz[i] = 1, scanf("%d", tl + i); 77 p[i] = min(tl[i] + i, n + 1); 78 tl[i] = p[i]; 79 } 80 sz[n + 1] = 1; 81 82 int m; scanf("%d", &m); 83 while(m--) { 84 int cmd, a, b; 85 scanf("%d%d", &cmd, &a), ++a; 86 if(cmd == 1) { 87 access(a), splay(a); 88 printf("%d\n", sz[a] - 1); 89 } else { 90 scanf("%d", &b); 91 int y = min(a + b, n + 1); 92 if(y != tl[a]) Link(a, tl[a] = y); 93 } 94 } 95 96 return 0; 97 }