【模板】替罪羊树

如题,这是一个模板。。。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <cctype>
  6 
  7 inline void read(int & x)
  8 {
  9     x = 0;
 10     int k = 1;
 11     char c = getchar();
 12     while (!isdigit(c))
 13         if (c == '-') c = getchar(), k = -1;
 14         else c = getchar();
 15     while (isdigit(c))
 16         x = (x << 1) + (x << 3) + (c ^ 48),
 17         c = getchar();
 18     x *= k;
 19 }
 20 
 21 const int MAXN = 201010, inf = 2e9;
 22 const double alpha = 0.9; //ƽºâÒò×Ó 
 23 int m, x, opt, tot = 0, top = 0, len, goat, root;
 24 int cur[MAXN], all[MAXN], faz[MAXN], son[MAXN][2], val[MAXN], stk[MAXN], siz[MAXN], ext[MAXN];
 25 
 26 inline int isbalace(int u)
 27 {
 28     return (double)siz[u] * alpha > (double)std::max(siz[son[u][0]], siz[son[u][1]]);
 29 }
 30 
 31 inline int Getson(int u)
 32 {
 33     return son[faz[u]][1] == u;
 34 }
 35 
 36 void Recycle(int u)
 37 {
 38     if (!u) return;
 39     Recycle(son[u][0]);
 40     cur[++top] = u;
 41     Recycle(son[u][1]);
 42 }
 43 
 44 int Build(int l, int r)
 45 {
 46     if (l > r) return 0;
 47     int mid = l + r >> 1, u = cur[mid];
 48     faz[son[u][0] = Build(l, mid - 1)] = u;
 49     faz[son[u][1] = Build(mid + 1, r)] = u;
 50     siz[u] = siz[son[u][0]] + siz[son[u][1]] + 1; 
 51     return u;
 52 }
 53 
 54 inline void Rebuild(int u)
 55 {
 56     top = 0;
 57     Recycle(u);
 58     int y = faz[u], ch = Getson(u), rt = Build(1, top);
 59     faz[son[y][ch] = rt] = y;
 60     if (u == root) root = rt;
 61 }
 62 
 63 void Insert(int x)
 64 {
 65     if (!root) 
 66     {
 67         siz[root = ++tot] = 1;
 68         faz[root] = 0;
 69         val[root] = x;
 70         return;
 71     }
 72     int u = root;
 73     while (true)
 74     {
 75         ++siz[u];
 76         int y = u;
 77         if (x >= val[u]) u = son[u][1];
 78         else u = son[u][0];
 79         if (!u)
 80         {
 81             siz[++tot] = 1;
 82             val[tot] = x;
 83             faz[tot] = y;
 84             son[y][x >= val[y]] = tot;
 85             break;
 86         }
 87     }
 88     int goat(0);
 89     for (int i = tot; i; i = faz[i])
 90         if (!isbalace(i)) goat = i;
 91     if (goat) Rebuild(goat);
 92 }
 93 
 94 inline int Getx(int x)
 95 {
 96     int u = root;
 97     while (u)
 98         if (x == val[u]) return u;
 99         else if (x >= val[u]) u = son[u][1];
100         else u = son[u][0];
101     return u;
102 }
103 
104 inline void Del(int u)
105 {
106     if (son[u][0] && son[u][1])
107     {
108         int s = son[u][0];
109         while (son[s][1]) s = son[s][1];
110         val[u] = val[s], u = s;
111     }
112     int s = son[u][0] ? son[u][0] : son[u][1],
113         y = faz[u], ch = Getson(u);
114     son[y][ch] = s, faz[s] = y;
115     for (int i = y; i; i = faz[i]) --siz[i];
116     if (root == u) root = s;
117 }
118 
119 inline void Delete(int x)
120 {
121     int u = Getx(x); 
122     if (u) Del(u);
123 }
124 
125 inline int Getrank(int x)
126 {
127     int u = root, ans = 1;
128     while (u)
129         if (x <= val[u]) u = son[u][0];
130         else ans += siz[son[u][0]] + 1, u = son[u][1];
131     return ans;
132 }
133 
134 inline int Getkth(int k)
135 {
136     int u = root;
137     while (u)
138     {
139         if (k <= siz[son[u][0]])
140         { u = son[u][0]; continue; }
141         k -= siz[son[u][0]] + 1;
142         if (!k) return val[u];
143         u = son[u][1];
144     }
145 }
146 
147 inline int Pre(int x)
148 {
149     int ans = -inf, u = root;
150     while (u)
151         if (val[u] < x) ans = std::max(ans, val[u]), u = son[u][1];
152         else u = son[u][0];
153     return ans;
154 }
155 
156 inline int Suf(int x)
157 {
158     int ans = inf, u = root;
159     while (u)
160         if (val[u] > x) ans = std::min(ans, val[u]), u = son[u][0];
161         else u = son[u][1];
162     return ans;
163 }
164 
165 signed main()
166 {
167     read(m);
168     for (int i = 1; i <= m; ++i)
169     {    
170         read(opt), read(x);
171         if (opt == 1) Insert(x);
172         if (opt == 2) Delete(x);
173         if (opt == 3) printf("%d\n", Getrank(x));
174         if (opt == 4) printf("%d\n", Getkth(x));
175         if (opt == 5) printf("%d\n", Pre(x));
176         if (opt == 6) printf("%d\n", Suf(x));
177     }
178     return 0;
179 }

 

posted @ 2018-12-03 12:31  Christopher_Yan  阅读(139)  评论(0编辑  收藏  举报