很早就有人给我推荐的模版题,然后我最近才刷的(‘ ‘ ) 昨天的tree 不知道比他们高到哪里去了,我和他谈笑风生啊!
bzoj 2002 弹飞绵羊
重点:这道题的cut和link 由于这道题链的特殊性所以不能用提根的方法搞,可以注意到每一次cut位置一定是前面的一个元素,所以access 上去之后直接把左边的儿子丢掉就行了(我原来的cut 是在不知道两个点的儿子关系时就强行提根(‘ ‘ )) 然后link的时候直接把cut的那一棵splay接过去就行了
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 200100; 8 struct node { 9 int size, p, data; 10 node* son[2], *fa; 11 }tr[maxn]; 12 13 14 void test(node* x) { 15 if(x) { 16 cout << x-> data <<" " << x-> size <<" "<< x-> p << endl; 17 for(int i = 0 ; i < 2; ++ i) test(x-> son[i]); 18 } 19 } 20 void update(node* x) { 21 x-> size = 1; 22 for(int i = 0; i < 2; ++ i) if(x-> son[i]) x-> size += x-> son[i]-> size; 23 } 24 25 void rotate(node* x, int f) { 26 node* y = x-> fa; 27 if(y-> fa) { 28 if(y-> fa-> son[0] == y) y-> fa-> son[0] = x; 29 else y-> fa-> son[1] = x; 30 } 31 x-> fa = y-> fa, y-> fa = x, x-> p = y-> p, x-> size = y-> size; 32 y-> son[f] = x-> son[!f]; 33 if(x->son[!f]) x-> son[!f]-> fa = y; 34 x-> son[!f] = y; 35 update(y); 36 } 37 38 void splay(node* x, node* f) { 39 while(x-> fa != f) { 40 if(x-> fa-> fa == f) { 41 int a = x-> fa-> son[0] == x ? 0 : 1; 42 rotate(x, a); 43 } 44 else { 45 node* y = x-> fa, *z = y-> fa; 46 int a = z-> son[0] == y ? 0 : 1; 47 int b = y-> son[0] == x ? 0 : 1; 48 if(a == b) rotate(y, a), rotate(x, b); 49 else rotate(x, b), rotate(x, a); 50 } 51 } 52 } 53 54 void access(int cur) { 55 node* x = tr + cur; node* y; int pp; 56 splay(x, NULL); 57 if(x-> son[1]) x-> son[1]-> p = cur, x-> son[1]-> fa = NULL, x-> son[1] = NULL, update(x); 58 while((pp = x-> p)) { 59 y = tr + pp; splay(y, NULL); 60 if(y-> son[1]) y-> son[1]-> p = pp, y-> son[1]-> fa = NULL, y-> son[1] = NULL, update(y); 61 y-> son[1] = x, x-> fa = y; update(y); 62 splay(x, NULL); 63 } 64 } 65 66 int int_get() { 67 int x = 0; char c = (char)getchar(); bool f = 0; 68 while(!isdigit(c) && c != ‘-‘) c = (char)getchar(); 69 if(c == ‘-‘) f = 1, c = (char)getchar(); 70 while(isdigit(c)) { 71 x = x * 10 + (int)(c - ‘0‘); 72 c = (char)getchar(); 73 } 74 if(f) x = -x; 75 return x; 76 } 77 78 int n, m, px[maxn]; 79 80 void read() { 81 n = int_get(); 82 for(int i = 1; i <= n; ++ i) { 83 int ne = int_get(); 84 px[i] = ne + i > n ? 0 : i + ne; 85 (tr + i)-> size = 1, (tr + i)-> p = px[i], (tr + i)-> data = i; 86 } 87 } 88 89 void sov() { 90 int m = int_get(); 91 while(m --) { 92 int op = int_get(); 93 if(op == 1) { 94 int x = int_get() + 1; access(x); printf("%d\n", (tr + x)-> size); 95 } 96 else { 97 int a, b; 98 a = int_get() + 1, b = int_get(); 99 access(a); node* x = tr + a; 100 if(px[a]) x-> son[0]-> p = 0, x-> son[0]-> fa = NULL, x-> son[0] = NULL; update(x); 101 px[a] = a + b > n ? 0 : a + b; 102 x-> p = px[a]; 103 } 104 } 105 } 106 107 int main() { 108 freopen("test.in", "r", stdin); 109 freopen("test.out", "w", stdout); 110 read(); 111 sov(); 112 return 0; 113 }
bzoj 2049 洞穴勘探
非常裸的操作,不过我查询是在splay上暴力,应该有更好的方法(‘ ‘ )
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 21000; 8 9 struct node { 10 int size, p, lr, data; 11 node *son[2], *fa; 12 }tr[maxn]; 13 14 void test(node* x) { 15 if(x) { 16 cout << x-> data <<" "<< x-> size <<" "<< x-> p <<" "<< x-> lr << endl; 17 for(int i = 0; i < 2; ++ i) test(x-> son[i]); 18 } 19 } 20 21 void update(node* x) { 22 x-> size = 1; 23 for(int i = 0; i < 2; ++ i) if(x-> son[i]) x-> size += x-> son[i]-> size; 24 } 25 26 void swap(node* &a, node* &b) { 27 node* mid = a; a = b, b = mid; 28 } 29 30 void pushdown(node* x) { 31 if(x && x-> lr) { 32 swap(x-> son[0], x-> son[1]); 33 for(int i = 0; i < 2; ++ i) if(x-> son[i]) x-> son[i]-> lr ^= 1; 34 x-> lr = 0; 35 } 36 } 37 38 void rotate(node* x, int f) { 39 node* y = x-> fa; 40 if(y-> fa) { 41 if(y-> fa-> son[0] == y) y-> fa-> son[0] = x; 42 else y-> fa-> son[1] = x; 43 } 44 x-> fa = y-> fa, y-> fa = x, x-> size = y-> size, x-> p = y-> p; 45 y-> son[f] = x-> son[!f]; 46 if(x-> son[!f]) x-> son[!f]-> fa = y; 47 x-> son[!f] = y; 48 update(y); 49 } 50 51 void splay(node* x, node* f) { 52 pushdown(x); 53 while(x-> fa != f) { 54 pushdown(x-> fa-> fa), pushdown(x-> fa), pushdown(x); 55 if(x-> fa-> fa == f) { 56 int a = x-> fa-> son[0] == x ? 0 : 1; 57 rotate(x, a); 58 } 59 else { 60 node* y = x-> fa, *z = y-> fa; 61 int a = z-> son[0] == y ? 0 : 1; 62 int b = y-> son[0] == x ? 0 : 1; 63 if(a == b) rotate(y, a), rotate(x, b); 64 else rotate(x, b), rotate(x, a); 65 } 66 } 67 } 68 69 void access(int cur) { 70 node* x = tr + cur, *y; int pp; 71 splay(x, NULL); if(x-> son[1]) x-> son[1]-> fa = NULL, x-> son[1]-> p = cur, x-> son[1] = NULL, update(x); 72 while((pp = x-> p)) { 73 y = tr + pp; splay(y, NULL); 74 if(y-> son[1]) y-> son[1]-> fa = NULL, y-> son[1]-> p = pp, y-> son[1] = NULL, update(y); 75 y-> son[1] = x, x-> fa = y; update(y); 76 splay(x, NULL); 77 } 78 } 79 80 void reserve(int cur) { 81 access(cur); 82 (tr + cur)-> lr ^= 1; 83 } 84 85 void cut(int a, int b) { 86 reserve(a), access(b); 87 (tr + a)-> p = 0, (tr + a)-> fa = NULL, (tr + b)-> son[0] = NULL; 88 update(tr + a), update(tr + b); 89 } 90 91 void link(int a, int b) { 92 reserve(a), access(b); 93 (tr + a)-> p = b; 94 update(a + tr), update(b + tr); 95 } 96 97 bool query(int a, int b) { 98 reserve(a); access(b); 99 node* x = tr + a; 100 while(x-> fa) x = x-> fa; 101 return x == (tr + b); 102 } 103 104 int int_get() { 105 int x = 0; char c = (char)getchar(); bool f = 0; 106 while(!isdigit(c) && c != ‘-‘ ) c = (char)getchar(); 107 if(c == ‘-‘) c = (char)getchar(), f = 1; 108 while(isdigit(c)) { 109 x = x * 10 + (int)(c - ‘0‘); 110 c = (char)getchar(); 111 } 112 if(f) x = -x; 113 return x; 114 } 115 116 int n, m; 117 118 void sov() { 119 n = int_get(), m = int_get(); 120 for(int i = 1; i <= n; ++ i) (tr + i)-> size = 1, (tr + i)-> p = (tr + i)-> lr = 0, (tr + i)-> data = i; 121 while(m --) { 122 char s[10]; scanf("%s", s + 1); 123 int a, b; a = int_get(), b = int_get(); 124 if(s[1] == ‘C‘) link(a, b); 125 if(s[1] == ‘D‘) cut(a, b); 126 if(s[1] == ‘Q‘) { 127 if(query(a, b)) printf("Yes\n"); 128 else printf("No\n"); 129 } 130 } 131 } 132 133 int main() { 134 //freopen("test.in", "r", stdin); 135 sov(); 136 // test(tr + 123); 137 }
时间: 2024-10-14 01:36:34