bzoj 3224/Tyvj 1728 普通平衡树
原题链接:http://www.tyvj.cn/p/1728
这道题以前用c语言写的treap水过了。。
现在接触了c++用sbt重写一遍(速度比treap快一些)。。。
sb树的一些基本操作都在里面了带垃圾回收,具体如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<iostream> 4 #include<algorithm> 5 const int MAX_N = 100100; 6 struct Node{ 7 int v, s, c; 8 Node *ch[2]; 9 inline void set(int _v, int _s, Node *p){ 10 v = _v, s = c = _s; 11 ch[0] = ch[1] = p; 12 } 13 inline void push_up(){ 14 s = ch[0]->s + ch[1]->s + c; 15 } 16 inline int cmp(int x) const{ 17 return x == v ? -1 : x > v; 18 } 19 }; 20 struct SizeBalanceTree{ 21 Node stack[MAX_N]; 22 Node *root, *null, *tail; 23 Node *store[MAX_N]; 24 int top; 25 void init(){ 26 tail = &stack[0]; 27 null = tail++; 28 null->set(0, 0, NULL); 29 root = null; 30 top = 0; 31 } 32 inline Node *newNode(int v){ 33 Node *p = null; 34 if (top) p = store[--top]; 35 else p = tail++; 36 p->set(v, 1, null); 37 return p; 38 } 39 inline void rotate(Node* &x, int d){ 40 Node *k = x->ch[!d]; 41 x->ch[!d] = k->ch[d]; 42 k->ch[d] = x; 43 k->s = x->s; 44 x->push_up(); 45 x = k; 46 } 47 inline void Maintain(Node* &x, int d){ 48 if (x->ch[d] == null) return; 49 if (x->ch[d]->ch[d]->s > x->ch[!d]->s){ 50 rotate(x, !d); 51 } else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s){ 52 rotate(x->ch[d], d), rotate(x, !d); 53 } else { 54 return; 55 } 56 Maintain(x, 0), Maintain(x, 1); 57 } 58 inline void insert(Node* &x, int v){ 59 if (x == null){ 60 x = newNode(v); 61 return; 62 } else { 63 x->s++; 64 int d = x->cmp(v); 65 if (-1 == d){ 66 x->c++; 67 return; 68 } 69 insert(x->ch[d], v); 70 x->push_up(); 71 Maintain(x, d); 72 } 73 } 74 inline void del(Node* &x, int v){ 75 if (x == null) return; 76 x->s--; 77 int d = x->cmp(v); 78 if (-1 == d){ 79 if (x->c > 1){ 80 x->c--; 81 return; 82 } else if (x->ch[0] == null || x->ch[1] == null){ 83 store[top++] = x; 84 x = x->ch[0] == null ? x->ch[1] : x->ch[0]; 85 } else { 86 Node *ret = x->ch[1]; 87 for (; ret->ch[0] != null; ret = ret->ch[0]); 88 del(x->ch[1], x->v = ret->v); 89 } 90 } else { 91 del(x->ch[d], v); 92 } 93 if (x != null) x->push_up(); 94 } 95 inline void insert(int v){ 96 insert(root, v); 97 } 98 inline void del(int v){ 99 del(root, v); 100 } 101 inline void kth(int k){ 102 int t; 103 Node *x = root; 104 for (; x->s;){ 105 t = x->ch[0]->s; 106 if (k <= t) x = x->ch[0]; 107 else if (t + 1 <= k && k <= t + x->c) break; 108 else k -= t + x->c, x = x->ch[1]; 109 } 110 printf("%d\n", x->v); 111 } 112 inline void rank(int v){ 113 int t, cur; 114 Node *x = root; 115 for (cur = 0; x->s;){ 116 t = x->ch[0]->s; 117 if (v == x->v) break; 118 else if (v < x->v) x = x->ch[0]; 119 else cur += t + x->c, x = x->ch[1]; 120 } 121 printf("%d\n", cur + t + 1); 122 } 123 inline void succ(int v){ 124 int ret = 0; 125 Node *x = root; 126 while (x->s){ 127 if (x->v > v) ret = x->v, x = x->ch[0]; 128 else x = x->ch[1]; 129 } 130 printf("%d\n", ret); 131 } 132 inline void pred(int v){ 133 int ret = 0; 134 Node *x = root; 135 while (x->s){ 136 if (x->v < v) ret = x->v, x = x->ch[1]; 137 else x = x->ch[0]; 138 } 139 printf("%d\n", ret); 140 } 141 }SBT; 142 int main(){ 143 #ifdef LOCAL 144 freopen("in.txt", "r", stdin); 145 freopen("out.txt", "w+", stdout); 146 #endif 147 SBT.init(); 148 int n, op, v; 149 scanf("%d", &n); 150 while (n--){ 151 scanf("%d %d", &op, &v); 152 if (1 == op) SBT.insert(v); 153 else if (2 == op) SBT.del(v); 154 else if (3 == op) SBT.rank(v); 155 else if (4 == op) SBT.kth(v); 156 else if (5 == op) SBT.pred(v); 157 else SBT.succ(v); 158 } 159 return 0; 160 }
2015/6/11
update:加了读优化外挂,精简了一下程序。。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define all(c) (c).begin(), (c).end() 6 #define iter(c) decltype((c).begin()) 7 #define cpresent(c, e) (find(all(c), (e)) != (c).end()) 8 #define rep(i, n) for (int i = 0; i < (int)(n); i++) 9 #define tr(c, i) for (iter(c) i = (c).begin(); i != (c).end(); ++i) 10 #define pb(e) push_back(e) 11 #define mp(a, b) make_pair(a, b) 12 const int Max_N = 100100; 13 typedef unsigned long long ull; 14 inline int read() { 15 char c; int r; 16 while (((c = getchar()) < '0' || c > '9') && c ^ '-'); 17 bool f = c == '-'; if (f) r = 0; else r = c - '0'; 18 while ((c = getchar()) >= '0' && c <= '9') (r *= 10) += c - '0'; 19 if (f) return -r; else return r; 20 } 21 struct Node { 22 int v, s, c; 23 Node *ch[2]; 24 inline void setc(int _v, int _s, Node *p) { 25 v = _v, s = c = _s; 26 ch[0] = ch[1] = p; 27 } 28 inline void push_up() { 29 s = ch[0]->s + ch[1]->s + c; 30 } 31 inline int cmp(int x) const { 32 return x == v ? -1 : x > v; 33 } 34 }; 35 struct SizeBalanceTree { 36 int top; 37 Node *null, *root, *tail; 38 Node stack[Max_N], *pool[Max_N]; 39 inline void init() { 40 top = 0; 41 tail = &stack[0]; 42 null = tail++; 43 null->setc(0, 0, NULL); 44 root = null; 45 } 46 inline Node *newNode(int v) { 47 Node *x = !top ? tail++ : pool[--top]; 48 x->setc(v, 1, null); 49 return x; 50 } 51 inline void rotate(Node *&x, int d) { 52 Node *k = x->ch[!d]; x->ch[!d] = k->ch[d], k->ch[d] = x; 53 k->s = x->s; x->push_up(); x = k; 54 } 55 inline void Maintain(Node *&x, int d) { 56 if (!x->ch[d]->s) return; 57 if (x->ch[d]->ch[d]->s > x->ch[!d]->s) rotate(x, !d); 58 else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s) rotate(x->ch[d], d), rotate(x, !d); 59 else return; 60 Maintain(x, 0), Maintain(x, 1); 61 } 62 inline void insert(Node *&x, int v) { 63 if (!x->s) { x = newNode(v); return; } 64 x->s++; 65 int d = x->cmp(v); 66 if (-1 == d) { x->c++; return; } 67 insert(x->ch[d], v); 68 x->push_up(); 69 Maintain(x, d); 70 } 71 inline void erase(Node *&x, int p) { 72 if (!x->s) return; 73 x->s--; 74 int d = x->cmp(p); 75 if (-1 == d) { 76 if (x->c > 1) { x->c--; return; } 77 else if (!x->ch[0]->s || !x->ch[1]->s) { 78 pool[top++] = x; 79 x = x->ch[0]->s ? x->ch[0] : x->ch[1]; 80 } else { 81 Node *ret = x->ch[1]; 82 for (; ret->ch[0]->s; ret = ret->ch[0]); 83 erase(x->ch[1], x->v = ret->v); 84 } 85 } else { 86 erase(x->ch[d], p); 87 } 88 } 89 inline void insert(int v) { 90 insert(root, v); 91 } 92 inline void erase(int v) { 93 erase(root, v); 94 } 95 inline void kth(int k) { 96 int t; 97 Node *x = root; 98 for (; x->s;) { 99 t = x->ch[0]->s; 100 if (k <= t) x = x->ch[0]; 101 else if (t + 1 <= k && k <= t + x->c) break; 102 else k -= t + x->c, x = x->ch[1]; 103 } 104 printf("%d\n", x->v); 105 } 106 inline void rank(int v) { 107 int t, cur; 108 Node *x = root; 109 for (cur = 0; x->s;) { 110 t = x->ch[0]->s; 111 if (v == x->v) break; 112 else if (v < x->v) x = x->ch[0]; 113 else cur += t + x->c, x = x->ch[1]; 114 } 115 printf("%d\n", cur + t + 1); 116 } 117 inline void succ(int v) { 118 int ret = 0; 119 Node *x = root; 120 while (x->s) { 121 if (x->v > v) ret = x->v, x = x->ch[0]; 122 else x = x->ch[1]; 123 } 124 printf("%d\n", ret); 125 } 126 inline void pred(int v) { 127 int ret = 0; 128 Node *x = root; 129 while (x->s) { 130 if (x->v < v) ret = x->v, x = x->ch[1]; 131 else x = x->ch[0]; 132 } 133 printf("%d\n", ret); 134 } 135 }sbt; 136 int main(){ 137 #ifdef LOCAL 138 freopen("in.txt", "r", stdin); 139 freopen("out.txt", "w+", stdout); 140 #endif 141 sbt.init(); 142 int n, op, v; 143 n = read(); 144 while (n--){ 145 op = read(), v = read(); 146 if (1 == op) sbt.insert(v); 147 else if (2 == op) sbt.erase(v); 148 else if (3 == op) sbt.rank(v); 149 else if (4 == op) sbt.kth(v); 150 else if (5 == op) sbt.pred(v); 151 else sbt.succ(v); 152 } 153 return 0; 154 }
By: GadyPu 博客地址:http://www.cnblogs.com/GadyPu/ 转载请说明