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

 

你可能感兴趣的:(ZOJ)