原题链接: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<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<vector> 7 #include<map> 8 #include<set> 9 using std::cin; 10 using std::cout; 11 using std::endl; 12 using std::find; 13 using std::set; 14 using std::map; 15 using std::pair; 16 using std::vector; 17 using std::multiset; 18 using std::multimap; 19 #define all(c) (c).begin(), (c).end() 20 #define iter(c) decltype((c).begin()) 21 #define cpresent(c, e) (find(all(c), (e)) != (c).end()) 22 #define rep(i, n) for (int i = 0; i < (int)(n); i++) 23 #define tr(c, i) for (iter(c) i = (c).begin(); i != (c).end(); ++i) 24 #define pb(e) push_back(e) 25 #define mp(a, b) make_pair(a, b) 26 const int Max_N = 100100; 27 typedef unsigned long long ull; 28 inline int read() { 29 char c; int r; 30 while (((c = getchar()) < '0' || c > '9') && c ^ '-'); 31 bool f = c == '-'; if (f) r = 0; else r = c - '0'; 32 while ((c = getchar()) >= '0' && c <= '9') (r *= 10) += c - '0'; 33 if (f) return -r; else return r; 34 } 35 struct Node { 36 int v, s, c; 37 Node *ch[2]; 38 inline void setc(int _v, int _s, Node *p) { 39 v = _v, s = c = _s; 40 ch[0] = ch[1] = p; 41 } 42 inline void push_up() { 43 s = ch[0]->s + ch[1]->s + c; 44 } 45 inline int cmp(int x) const { 46 return x == v ? -1 : x > v; 47 } 48 }; 49 struct SizeBalanceTree { 50 int top; 51 Node *null, *root, *tail; 52 Node stack[Max_N], *pool[Max_N]; 53 inline void init() { 54 top = 0; 55 tail = &stack[0]; 56 null = tail++; 57 null->setc(0, 0, NULL); 58 root = null; 59 } 60 inline Node *newNode(int v) { 61 Node *x = !top ? tail++ : pool[--top]; 62 x->setc(v, 1, null); 63 return x; 64 } 65 inline void rotate(Node *&x, int d) { 66 Node *k = x->ch[!d]; x->ch[!d] = k->ch[d], k->ch[d] = x; 67 k->s = x->s; x->push_up(); x = k; 68 } 69 inline void Maintain(Node *&x, int d) { 70 if (!x->s) return; 71 if (x->ch[d]->ch[d]->s > x->ch[!d]->s) rotate(x, !d); 72 else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s) rotate(x->ch[d], d), rotate(x, !d); 73 else return; 74 Maintain(x, 0), Maintain(x, 1); 75 } 76 inline void insert(Node *&x, int v) { 77 if (!x->s) { x = newNode(v); return; } 78 x->s++; 79 int d = x->cmp(v); 80 if (-1 == d) { x->c++; return; } 81 insert(x->ch[d], v); 82 x->push_up(); 83 Maintain(x, d); 84 } 85 inline void erase(Node *&x, int p) { 86 if (!x->s) return; 87 x->s--; 88 int d = x->cmp(p); 89 if (-1 == d) { 90 if (x->c > 1) { x->c--; return; } 91 else if (!x->ch[0]->s || !x->ch[1]->s) { 92 pool[top++] = x; 93 x = x->ch[0]->s ? x->ch[0] : x->ch[1]; 94 } else { 95 Node *ret = x->ch[1]; 96 for (; ret->ch[0]->s; ret = ret->ch[0]); 97 erase(x->ch[1], x->v = ret->v); 98 } 99 } else { 100 erase(x->ch[d], p); 101 } 102 } 103 inline void insert(int v) { 104 insert(root, v); 105 } 106 inline void erase(int v) { 107 erase(root, v); 108 } 109 inline void kth(int k) { 110 int t; 111 Node *x = root; 112 for (; x->s;) { 113 t = x->ch[0]->s; 114 if (k <= t) x = x->ch[0]; 115 else if (t + 1 <= k && k <= t + x->c) break; 116 else k -= t + x->c, x = x->ch[1]; 117 } 118 printf("%d\n", x->v); 119 } 120 inline void rank(int v) { 121 int t, cur; 122 Node *x = root; 123 for (cur = 0; x->s;) { 124 t = x->ch[0]->s; 125 if (v == x->v) break; 126 else if (v < x->v) x = x->ch[0]; 127 else cur += t + x->c, x = x->ch[1]; 128 } 129 printf("%d\n", cur + t + 1); 130 } 131 inline void succ(int v) { 132 int ret = 0; 133 Node *x = root; 134 while (x->s) { 135 if (x->v > v) ret = x->v, x = x->ch[0]; 136 else x = x->ch[1]; 137 } 138 printf("%d\n", ret); 139 } 140 inline void pred(int v) { 141 int ret = 0; 142 Node *x = root; 143 while (x->s) { 144 if (x->v < v) ret = x->v, x = x->ch[1]; 145 else x = x->ch[0]; 146 } 147 printf("%d\n", ret); 148 } 149 }sbt; 150 int main(){ 151 #ifdef LOCAL 152 freopen("in.txt", "r", stdin); 153 freopen("out.txt", "w+", stdout); 154 #endif 155 sbt.init(); 156 int n, op, v; 157 n = read(); 158 while (n--){ 159 op = read(), v = read(); 160 if (1 == op) sbt.insert(v); 161 else if (2 == op) sbt.erase(v); 162 else if (3 == op) sbt.rank(v); 163 else if (4 == op) sbt.kth(v); 164 else if (5 == op) sbt.pred(v); 165 else sbt.succ(v); 166 } 167 return 0; 168 }