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 }
View Code

 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 }
View Code

 

posted @ 2015-04-24 17:54  GadyPu  阅读(335)  评论(0编辑  收藏  举报