替罪羊树
存个板子
// Cease to struggle and you cease to live // a.cpp // Created by hjj on 2019_07_17 16:24 #include <bits/stdc++.h> using namespace std; const int MAXM = 100005 * 15; struct BST{ int val[MAXM], ext[MAXM], fa[MAXM]; int sz[MAXM], tsz[MAXM]; int son[MAXM][2]; int root; double alp; int stn, st[MAXM]; BST(){ stn = MAXM - 1; for(int i = 0; i < MAXM; i++) st[i] = i; root = 0; alp = 0.7; } int newnode(int x) { int v = st[--stn]; val[v] = x; ext[v] = 1;fa[v] = 0; sz[v] = tsz[v] = 0; son[v][0] = son[v][1] = 0; return v; } void push_up(int x) { sz[x] = ext[x];tsz[x] = 1; if(son[x][0]) { sz[x] += sz[son[x][0]]; tsz[x] += tsz[son[x][0]]; } if(son[x][1]) { sz[x] += sz[son[x][1]]; tsz[x] += tsz[son[x][1]]; } } bool isBad(int v) { return (double(tsz[ son[v][0] ]) > double(tsz[v]) * alp) || (double(tsz[ son[v][1] ]) > double(tsz[v]) * alp) || (sz[v] * 2 < tsz[v]); } vector<int> vec; void rebuild_dfs(int v) { if(son[v][0]) rebuild_dfs(son[v][0]); if(ext[v])vec.push_back(v);else st[stn++] = v; if(son[v][1]) rebuild_dfs(son[v][1]); } int rebuild_build(int l, int r) { int mid = (l + r) >> 1, v = vec[mid]; son[v][0] = (l <= mid-1) ? rebuild_build(l, mid - 1) : 0; if(son[v][0]) fa[son[v][0]] = v; son[v][1] = (mid+1 <= r) ? rebuild_build(mid + 1, r) : 0; if(son[v][1]) fa[son[v][1]] = v; push_up(v); return v; } void rebuild(int v) { if(isBad(v)){ vec.clear(); int tfa = fa[v], lr = son[tfa][1] == v; rebuild_dfs(v); int u = 0; if(vec.size()) u = rebuild_build(0, vec.size() - 1); if(tfa == 0) fa[u] = 0, root = u; else{ son[tfa][lr] = u; if(u)fa[u] = tfa; } } } void ins(int x) { int p = root, q = root; for(;p && val[p] != x; q = p, p = son[p][ val[p] < x]) ; if(!q) { p = root = newnode(x); }else if(p) { ext[p]++; }else{ fa[p = son[q][val[q] < x] = newnode(x) ] = q; } int fg = 0; for(;p;p = fa[p]) { push_up(p); if(isBad(p)) fg = p; } if(fg) rebuild(fg); } void del(int x) { int p = root; for(;p && val[p] != x; p = son[p][ val[p] < x]); if(p && ext[p]){ --ext[p]; int fg = 0; for(;p; p = fa[p]) { push_up(p); if(isBad(p)) fg = p; } if(fg) rebuild(fg); } } int get_rank(int x) { int ret = 0; for(int p = root;p;) { if(val[p] < x) { ret += sz[son[p][0]] + ext[p]; p = son[p][1]; }else p = son[p][0]; } return ret + 1; } int get_Kth(int p, int k) { if(sz[son[p][0]] >= k) return get_Kth(son[p][0] ,k); k -= sz[son[p][0]]; if(ext[p] >= k) return val[p]; k -= ext[p]; return get_Kth(son[p][1], k); } int pre(int x) { int id = get_rank(x); return get_Kth(root, id - 1); } int nxt(int x) { int id = get_rank(x + 1); return get_Kth(root ,id); } }T; int main() { //ios::sync_with_stdio(0); cin.tie(0); cout.precision(6); cout << fixed; int n; scanf("%d", &n); for(int i = 1; i <= n; i++) { int op, x; scanf("%d %d", &op, &x); int ans; switch(op) { case 1 : T.ins(x);break; case 2 : T.del(x);break; case 3 : ans = T.get_rank(x); printf("%d\n", ans); break; case 4 : ans = T.get_Kth(T.root, x); printf("%d\n", ans); break; case 5: ans = T.pre(x); printf("%d\n", ans); break; case 6: ans = T.nxt(x); printf("%d\n", ans); break; } } return 0; }