LCT 模板 ——bzoj2002
http://www.lydsy.com/JudgeOnline/problem.php?id=2002
不说了,模板题, 将i的父亲改为i+ki就好。
1 /* 2 Name: bzoj2002 3 Author: rqy 4 Date: 14/02/17 5 */ 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 const int MAXN = 200010; 10 struct LCT{ 11 /*--Splay--*/ 12 int fa[MAXN], son[MAXN][2]; 13 int size[MAXN]; 14 bool rev[MAXN]; 15 inline void pd(int x) 16 { 17 if(rev[x]) 18 { 19 rev[son[x][0]] ^= 1; 20 rev[son[x][1]] ^= 1; 21 std::swap(son[x][0], son[x][1]); 22 rev[x] = 0; 23 } 24 } 25 inline void upd(int x) 26 { 27 size[x] = 1 + size[son[x][0]] + size[son[x][1]]; 28 } 29 inline int dir(int x) 30 { 31 return (son[fa[x]][0] == x) ? 0 : ((son[fa[x]][1] == x) ? 1 : -1); 32 } 33 inline void rotate(int x) 34 { 35 int p = fa[x], q = fa[p], d = dir(x), d2 = dir(p); 36 if(d < 0) return; 37 if(son[p][d] = son[x][d^1]) fa[son[p][d]] = p; 38 fa[son[x][d^1] = p] = x; 39 fa[x] = q; 40 if(d2 >= 0) son[q][d2] = x; 41 upd(p); 42 //??upd(x); 43 } 44 int stack[MAXN], st_end; 45 void splay(int x) 46 { 47 int i, j; 48 for(i = x, st_end = 0; dir(i) >= 0; i = fa[i]) 49 stack[st_end++] = i; 50 pd(i); 51 while(st_end--) pd(stack[st_end]); 52 for(; (i = dir(x)) >= 0; rotate(x)) 53 if((j = dir(fa[x])) >= 0) rotate(i ^ j ? x : fa[x]); 54 upd(x); 55 } 56 /*--LCT--*/ 57 LCT(){ 58 memset(fa, 0, sizeof(fa)); 59 memset(son, 0, sizeof(son)); 60 for(int i = 1; i < MAXN; i++) size[i] = 1; 61 size[0] = 0; 62 memset(rev, 0, sizeof(rev)); 63 } 64 void access(int x) 65 { 66 int f; 67 splay(x); 68 son[x][1] = 0; 69 //??upd(x); 70 while(f = fa[x]) 71 { 72 splay(f); 73 son[f][1] = x; 74 upd(x = f); 75 } 76 } 77 inline void mkroot(int x) 78 { 79 access(x); 80 splay(x); 81 rev[x] ^= 1; 82 } 83 inline void cut(int x, int y) 84 { 85 mkroot(x); 86 access(y); 87 splay(y); 88 son[y][0] = fa[x] = 0; 89 upd(y); 90 } 91 inline void link(int x, int y) 92 { 93 mkroot(x); 94 fa[x] = y; 95 access(x); 96 splay(x); 97 } 98 }; 99 LCT T; 100 int nxt[MAXN]; 101 int main() 102 { 103 //freopen("in", "r", stdin); 104 int n, m, x, i, j; 105 scanf("%d", &n); 106 for(i = 1; i <= n; i++) 107 { 108 scanf("%d", &x); 109 nxt[i] = T.fa[i] = std::min(i + x, n + 1); 110 } 111 scanf("%d", &m); 112 while(m--) 113 { 114 scanf("%d%d", &x, &i); i++; 115 if(x == 1) 116 { 117 T.mkroot(n + 1); 118 T.access(i); 119 T.splay(i); 120 printf("%d\n", T.size[T.son[i][0]]); 121 } 122 else 123 { 124 scanf("%d", &j); 125 T.cut(i, nxt[i]); 126 T.link(i, nxt[i] = std::min(i + j, n + 1)); 127 } 128 } 129 return 0; 130 }
1 /* 2 Name: bzoj2002 3 Author: rqy 4 Date: 15/02/17 09:50, 16/02/17 09:54 5 */ 6 #include<cstdio> 7 #include<algorithm> 8 9 struct LCT{ 10 struct Node{ 11 Node *fa, *son[2]; 12 int siz; 13 bool rev; 14 Node(Node *fa = NULL, Node *l = NULL, Node *r = NULL) :fa(fa), rev(0), siz(1) { 15 son[0] = l; 16 son[1] = r; 17 } 18 inline void upd() { siz = son[0]->siz + son[1]->siz + 1; } 19 inline void pd() { 20 if (rev) { 21 son[0]->rev ^= 1; 22 son[1]->rev ^= 1; 23 std::swap(son[0], son[1]); 24 rev = 0; 25 } 26 } 27 inline int tp() { return fa->son[0] == this ? 0 : (fa->son[1] == this ? 1 : -1); } 28 inline void rotate() { 29 int d = tp(); 30 if (d < 0) return; 31 Node *p = fa; 32 if ((p->son[d] = son[d^1])->siz) son[d^1]->fa = p; 33 fa = p->fa; 34 if (p->tp() >= 0) fa->son[p->tp()] = this; 35 (son[d^1] = p)->fa = this; 36 p->upd(); 37 //??upd(); 38 } 39 }; 40 Node* nil; 41 Node nodes[200010]; 42 Node* stack[200010]; 43 44 void init(int n) { 45 for (Node *i = nodes; i - nodes < n; ++i) 46 *i = Node(nil, nil, nil); 47 } 48 LCT(int n = 0) { 49 nil = new Node(); 50 nil->fa = nil->son[0] = nil->son[1] = nil; 51 nil->siz = 0; 52 init(n); 53 } 54 void splay(Node *x) { 55 Node *v = x, **t = stack; 56 for (; v != nil && v->tp() >= 0; v = v->fa) 57 *(t++) = v->fa; 58 while (t != stack) 59 (*(--t))->pd(); 60 x->pd(); 61 int i, j; 62 for (v = x->fa; (i = x->tp()) >= 0; x->rotate(), v = x->fa) 63 if ((j = v->tp()) >= 0) 64 (i ^ j ? x : v)->rotate(); 65 x->upd(); 66 } 67 void access(Node *x) { 68 Node *v; 69 splay(x); 70 x->son[1] = nil; 71 //??x->upd(); 72 while ((v = x->fa) != nil) { 73 splay(v); 74 v->son[1] = x; 75 (x = v)->upd(); 76 } 77 } 78 inline void mkroot(Node *x) { 79 access(x); 80 splay(x); 81 x->rev ^= 1; 82 } 83 inline void cut(int x, int y) { 84 //fa[x] == y -> fa[x] = 0 85 mkroot(nodes + x); 86 access(nodes + y); 87 splay(nodes + y); 88 nodes[y].son[0] = nodes[x].fa = nil; 89 nodes[y].upd(); 90 } 91 inline void link(int x, int y) { 92 //fa[x] == 0 -> fa[x] = y 93 mkroot(nodes + x); 94 nodes[x].fa = nodes + y; 95 access(nodes + x); 96 splay(nodes + x); 97 } 98 }; 99 LCT T; 100 int nxt[200010]; 101 int main() 102 { 103 //freopen("in", "r", stdin); 104 int n, m, x, i, j; 105 scanf("%d", &n); 106 T.init(n + 2); 107 for (i = 1; i <= n; i++) { 108 scanf("%d", &x); 109 T.nodes[i].fa = T.nodes + (nxt[i] = std::min(i + x, n + 1)); 110 } 111 scanf("%d", &m); 112 while (m--) { 113 scanf("%d%d", &x, &i); i++; 114 if (x == 1) { 115 T.mkroot(T.nodes + n + 1); 116 T.access(T.nodes + i); 117 T.splay(T.nodes + i); 118 printf("%d\n", T.nodes[i].son[0]->siz); 119 } else { 120 scanf("%d", &j); 121 T.cut(i, nxt[i]); 122 T.link(i, nxt[i] = std::min(i + j, n + 1)); 123 } 124 } 125 return 0; 126 }
1 /* 2 Name: bzoj2002 3 Author: rqy 4 Date: 17/02/17 08:03 5 */ 6 #include<cstdio> 7 #include<algorithm> 8 #include<cstring> 9 const int N = 200010; 10 int fa[N], son[N][2], siz[N]; 11 bool rev[N]; 12 #define f fa[x] 13 #define ch son[x] 14 inline int tp(int x) { 15 return son[f][0] == x ? 0 : 16 son[f][1] == x ? 1 : -1; 17 } 18 inline void pd(int x) { 19 if (rev[x]) { 20 rev[ch[0]] ^= 1; 21 rev[ch[1]] ^= 1; 22 std::swap(ch[0], ch[1]); 23 rev[x] = 0; 24 } 25 } 26 inline void upd(int x) { 27 siz[x] = siz[ch[0]] + siz[ch[1]] + 1; 28 } 29 inline void rotate(int x) { 30 int p = f, d = tp(x); 31 f = fa[p]; 32 if (tp(p) >= 0) 33 son[f][tp(p)] = x; 34 if (son[p][d] = ch[d ^ 1]) 35 fa[ch[d ^ 1]] = p; 36 son[fa[p] = x][d ^ 1] = p; 37 upd(p); 38 //upd(x); 39 } 40 int st[N]; 41 void splay(int x) { 42 int t = 0, v = x, i, j; 43 for (; tp(v) >= 0; v = fa[v], ++t) 44 st[t] = v; 45 pd(v); 46 for (; t >= 0; --t) 47 pd(st[t]); 48 for (; (i = tp(x)) >= 0; rotate(x)) 49 if((j = tp(f)) >= 0) 50 rotate(i ^ j ? x : f); 51 upd(x); 52 } 53 void init(int n) { 54 memset(fa, 0, sizeof(fa)); 55 memset(son, 0, sizeof(son)); 56 for (int i = 1; i <= n; i++) siz[i] = 1; 57 siz[0] = 0; 58 memset(rev, 0, sizeof(rev)); 59 } 60 void access(int x) { 61 splay(x); 62 ch[1] = 0; 63 //upd(x); 64 for (int v = f; v; v = f) { 65 splay(v); 66 son[v][1] = x; 67 upd(x = v); 68 } 69 } 70 inline void mkroot(int x) { 71 access(x); 72 splay(x); 73 rev[x] ^= 1; 74 } 75 inline void cut(int x, int y) { 76 mkroot(x); 77 access(y); 78 splay(y); 79 son[y][0] = fa[x] = 0; 80 upd(y); 81 } 82 inline void link(int x, int y) { 83 mkroot(x); 84 fa[x] = y; 85 access(x); 86 splay(x); 87 } 88 int nxt[N]; 89 int main() 90 { 91 //freopen("in", "r", stdin); 92 int n, m, x, i, j; 93 scanf("%d", &n); 94 init(n + 1); 95 for(i = 1; i <= n; i++) 96 { 97 scanf("%d", &x); 98 nxt[i] = fa[i] = std::min(i + x, n + 1); 99 } 100 scanf("%d", &m); 101 while(m--) 102 { 103 scanf("%d%d", &x, &i); i++; 104 if(x == 1) 105 { 106 mkroot(n + 1); 107 access(i); 108 splay(i); 109 printf("%d\n", siz[son[i][0]]); 110 } 111 else 112 { 113 scanf("%d", &j); 114 cut(i, nxt[i]); 115 link(i, nxt[i] = std::min(i + j, n + 1)); 116 } 117 } 118 return 0; 119 }