【模板】替罪羊树
如题,这是一个模板。。。
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 }