Splay模板
Splay(Tyvj 1728/Bzoj 3224 普通平衡树)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 struct node { 6 int data, size, cnt; 7 node *child[2], *father; 8 9 void pushup() { 10 size = child[0]->size + child[1]->size + cnt; 11 } 12 13 node() { 14 data = size = cnt = 0; 15 child[0] = child[1] = father = NULL; 16 } 17 18 } *root = new node, *nul = new node; 19 20 node* newnode(int data, node *fa) { 21 node *cur = new node; 22 cur->data = data, cur->size = cur->cnt = 1; 23 cur->child[0] = cur->child[1] = nul; cur->father = fa; 24 return cur; 25 } 26 27 bool getp(node *cur) { 28 return (cur->father->child[1] == cur); 29 } 30 31 void connect(node *x, node *y, int p) { 32 x->father = y; 33 y->child[p] = x; 34 } 35 36 void rotate(node *cur) { 37 int p = getp(cur), p2 = getp(cur->father); 38 node *r = cur->father->father; 39 connect(cur->child[p ^ 1], cur->father, p); 40 connect(cur->father, cur, p ^ 1); 41 connect(cur, r, p2); 42 cur->child[p ^ 1]->pushup(); cur->pushup(); 43 } 44 45 void splay(node *cur, node *to) { 46 while(cur->father != to) { 47 node *fa = cur->father, *gfa = cur->father->father; 48 if(gfa != to) { 49 if(getp(cur) == getp(fa)) rotate(fa); 50 else rotate(cur); 51 } 52 rotate(cur); 53 } 54 } 55 56 node *find(node *cur, int v) { 57 if(cur == nul) 58 return nul; 59 if(cur->data == v) { 60 splay(cur, root); 61 return cur; 62 } else return find(cur->child[v > cur->data], v); 63 } 64 65 void insert(node *&cur, node *fa, int v) { 66 if(cur == nul) { 67 cur = newnode(v, fa); 68 splay(cur, root); 69 } else if(cur->data == v) { 70 cur->cnt++; 71 splay(cur, root); 72 } else insert(cur->child[v > cur->data], cur, v); 73 cur->pushup(); 74 } 75 76 int rnk(node *cur, int v) { 77 if(cur == nul) return 1; 78 if(cur->data > v) return rnk(cur->child[0], v); 79 else if(cur->data < v) 80 return cur->child[0]->size + cur->cnt + rnk(cur->child[1], v); 81 else { 82 int ans = cur->child[0]->size + 1; 83 splay(cur, root); 84 return ans; 85 } 86 } 87 88 int findkth(node *cur, int k) { 89 if(k <= cur->child[0]->size) return findkth(cur->child[0], k); 90 else if(k > cur->child[0]->size + cur->cnt) 91 return findkth(cur->child[1], k - cur->child[0]->size - cur->cnt); 92 else { 93 splay(cur, root); 94 return cur->data; 95 } 96 } 97 98 void del(int v) { 99 node *cur = find(root->child[1], v), *lcbt = cur->child[0]; 100 if(cur->cnt > 1) { 101 cur->cnt--; 102 return; 103 } 104 while(lcbt->child[1] != nul) lcbt = lcbt->child[1]; 105 if(lcbt != nul) { 106 splay(lcbt, cur); 107 connect(lcbt, root, 1); 108 connect(cur->child[1], lcbt, 1); 109 lcbt->pushup(); 110 } else connect(cur->child[1], root, 1); 111 delete cur; 112 } 113 114 int main() { 115 ios::sync_with_stdio(false); 116 int n, opt, x; 117 cin >> n; 118 nul->father = nul->child[0] = nul->child[1] = nul; 119 root->father = root->child[0] = root->child[1] = nul; 120 root->data = 0x7fffffff; 121 while(n--) { 122 cin >> opt >> x; 123 if(opt == 1) insert(root->child[1], root, x); 124 if(opt == 2) del(x); 125 if(opt == 3) cout << rnk(root->child[1], x) << endl; 126 if(opt == 4) cout << findkth(root->child[1], x) << endl; 127 if(opt == 5) cout << findkth(root->child[1], rnk(root->child[1], x) - 1) << endl; 128 if(opt == 6) cout << findkth(root->child[1], rnk(root->child[1], x + 1)) << endl; 129 } 130 return 0; 131 }
Splay区间翻转 (Tyvj 1729/Bzoj3223 文艺平衡树)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int n, m; 6 7 struct node { 8 9 int val, size, tag; 10 node *child[2], *father; 11 12 node() { 13 val = size = tag = 0; 14 } 15 16 void pushup() { 17 size = child[0]->size + child[1]->size + 1; 18 } 19 20 void pushtag() { 21 if(tag) { 22 child[0]->tag ^= 1; 23 child[1]->tag ^= 1; 24 swap(child[0], child[1]); 25 tag = 0; 26 } 27 } 28 29 int wson() { 30 return this == father->child[1]; 31 } 32 33 } *root = new node, *nul = new node; 34 35 void init() { 36 nul->child[0] = nul->child[1] = nul->father = nul; 37 root->child[0] = root->child[1] = root->father = nul; 38 } 39 40 void connect(node *x, node *y, int p) { 41 x->father = y; y->child[p] = x; 42 } 43 44 node *newnode(int v, node *fa) { 45 node *cur = new node; 46 cur->val = v; cur->size = 1; 47 cur->child[0] = cur->child[1] = nul; 48 cur->father = fa; 49 return cur; 50 } 51 52 void rotate(node *&cur) { 53 int p = cur->wson(), fp = cur->father->wson(); 54 node *rt = cur->father->father; 55 connect(cur->child[p ^ 1], cur->father, p); 56 connect(cur->father, cur, p ^ 1); 57 connect(cur, rt, fp); 58 cur->child[p ^ 1]->pushup(); cur->pushup(); 59 } 60 61 void splay(node *cur, node *goal) { 62 while(cur->father != goal) { 63 node *fa = cur->father, *gfa = cur->father->father; 64 if(gfa != goal) { 65 if(cur->wson() == fa->wson()) rotate(fa); 66 else rotate(cur); 67 } 68 rotate(cur); 69 } 70 } 71 72 void build(node *&cur, node *fa, int l, int r) { 73 if(l <= r) { 74 int mid = (l + r) >> 1; 75 cur = newnode(mid, fa); 76 build(cur->child[0], cur, l, mid - 1); 77 build(cur->child[1], cur, mid + 1, r); 78 cur->pushup(); 79 } 80 } 81 82 node* findkth(node *cur, int k) { 83 cur->pushtag(); 84 if(k <= cur->child[0]->size) return findkth(cur->child[0], k); 85 else if(k > cur->child[0]->size + 1) 86 return findkth(cur->child[1], k - cur->child[0]->size - 1); 87 else return cur; 88 } 89 90 void reverse(int l, int r) 91 { 92 splay(findkth(root->child[1], l - 1), root); 93 splay(findkth(root->child[1], r + 1), root->child[1]); 94 root->child[1]->child[1]->child[0]->tag ^= 1; 95 } 96 97 void ldr(node *cur) { 98 if(cur == nul) return; 99 cur->pushtag(); 100 ldr(cur->child[0]); 101 if(cur->val != 1 && cur->val != n + 2) cout << cur->val - 1 << " "; 102 ldr(cur->child[1]); 103 } 104 105 int main() { 106 init(); 107 int x, y; 108 cin >> n >> m; 109 build(root->child[1], root, 1, n + 2); 110 while(m--) { 111 cin >> x >> y; 112 reverse(x + 1, y + 1); 113 } 114 ldr(root->child[1]); 115 cout << endl; 116 return 0; 117 }