模板题,不过看了leaderboard后发现了更好的递归式splay,等下学一下
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; struct Splay_tree { int f[maxn], ch[maxn][2], key[maxn], cnt[maxn], size[maxn], sz, root; void clear() { sz = root = 0; } void init0(int x) { f[x] = ch[x][0] = ch[x][1] = key[x] = cnt[x] = size[x] = 0; } void init(int x, int fa, int v) { f[x] = fa; ch[x][0] = ch[x][1] = 0; key[x] = v; cnt[x] = size[x] = 1; } int witch(int x) { return ch[f[x]][1]==x; } void update(int x) { if (!x) return; size[x] = cnt[x]; if (ch[x][0]) size[x] += size[ch[x][0]]; if (ch[x][1]) size[x] += size[ch[x][1]]; } void rotate(int x) { int y = f[x], z = f[y], px = witch(x), py = witch(y); ch[y][px]=ch[x][px^1]; f[ch[y][px]] = y; ch[x][px^1]=y; f[y] = x; f[x]=z; if (z) ch[z][py]=x; update(y); update(x); } void splay(int x) { for (int fa; (fa = f[x]); rotate(x)) if (f[fa]) rotate(witch(x)==witch(fa)?fa:x); root = x; } void insert(int v) { if (!root) { init(++sz, 0, v); root = sz; return; } int fa = 0, now = root; while (true) { if (now == 0) { init(++sz, fa, v); ch[fa][key[fa]<v]=sz; update(fa); splay(sz); break; } if (key[now]==v) { cnt[now]++; update(now); update(fa); splay(now); break; } fa = now; now = ch[now][key[now]<v]; } } int find(int v) { int ans = 0, now = root; while (true) { if (!now) return -1; if (v < key[now]) now = ch[now][0]; else { ans += (ch[now][0]?size[ch[now][0]]:0); if (v == key[now]) { splay(now); return ans+1; } ans += cnt[now]; now = ch[now][1]; } } } int findx(int x) { int now = root; while (true) { if (!now) return -1; if (ch[now][0] && x <= size[ch[now][0]]) now = ch[now][0]; else { int t = (ch[now][0]?size[ch[now][0]]:0)+cnt[now]; if (x <= t) return key[now]; x -= t; now = ch[now][1]; } } } int pre(){ int now=ch[root][0]; while (ch[now][1]) now=ch[now][1]; return now; } int next(){ int now=ch[root][1]; while (ch[now][0]) now=ch[now][0]; return now; } void del(int x) { int t = find(x); if (cnt[root] > 1) { cnt[root]--; update(root); return; } if (!ch[root][0]&&!ch[root][1]) { init0(root); root = 0; return; } if (!ch[root][0]) { t = root; root = ch[root][1]; f[root] = 0; init0(t); return; } if (!ch[root][1]) { t = root; root = ch[root][0]; f[root] = 0; init0(t); return; } int p = pre(); t = root; splay(p); f[ch[t][1]] = root; ch[root][1] = ch[t][1]; init0(t); update(root); } }splay_tree; int main() { splay_tree.sz = 0, splay_tree.root = 0; int T; scanf("%d", &T); while (T--) { int opt, x; scanf("%d%d", &opt, &x); if (opt == 1) splay_tree.insert(x); else if (opt == 2) splay_tree.del(x); else if (opt == 3) printf("%d\n", splay_tree.find(x)); else if (opt == 4) printf("%d\n", splay_tree.findx(x)); else if (opt == 5) { splay_tree.insert(x); printf("%d\n", splay_tree.key[splay_tree.pre()]); splay_tree.del(x); } else { splay_tree.insert(x); printf("%d\n", splay_tree.key[splay_tree.next()]); splay_tree.del(x); } } return 0; }