可持久化平衡树模板
代码思想十分简单,不赘述。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; #define reg register inline int read() { int res = 0;char ch = getchar();bool fu = 0; while(!isdigit(ch)) fu |= (ch == '-'), ch = getchar(); while(isdigit(ch)) res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar(); return fu ? -res : res; } #define N 500005 int n; int tot, rt[N]; int val[N * 50], ch[N * 50][2], siz[N * 50], pri[N * 50]; inline void update(int o) { siz[o] = siz[ch[o][0]] + siz[ch[o][1]] + 1; } inline int newnode(int v) { siz[++tot] = 1; val[tot] = v; pri[tot] = rand(); return tot; } inline void cpyfrom(int x, int y) { siz[x] = siz[y], val[x] = val[y], ch[x][0] = ch[y][0], ch[x][1] = ch[y][1], pri[x] = pri[y]; } int Merge(int x, int y) { if (x * y == 0) return x + y; int jd = ++tot; if (pri[x] < pri[y]) { cpyfrom(jd, x); ch[jd][1] = Merge(ch[jd][1], y); update(jd); return jd; } else { cpyfrom(jd, y); ch[jd][0] = Merge(x, ch[jd][0]); update(jd); return jd; } } void Split(int o, int k, int &x, int &y) { if (!o) {x = y = 0;return;} if (val[o] <= k) x = ++tot, cpyfrom(x, o), Split(ch[x][1], k, ch[x][1], y), update(x); else y = ++tot, cpyfrom(y, o), Split(ch[y][0], k, x, ch[y][0]), update(y); } inline void insert(int &root, int v) { int a = 0, b = 0; Split(root, v, a, b); root = Merge(Merge(a, newnode(v)), b); } inline void delet(int &root, int v) { int a = 0, b = 0, c = 0; Split(root, v, a, b); Split(a, v - 1, a, c); c = Merge(ch[c][0], ch[c][1]); root = Merge(Merge(a, c), b); } inline int rnk(int &root, int v) { int a = 0, b = 0; Split(root, v - 1, a, b); int res = siz[a]; root = Merge(a, b); return res; } inline int kth(int o, int k) { while(1) { if (siz[ch[o][0]] >= k) o = ch[o][0]; else if (k == siz[ch[o][0]] + 1) return o; else k -= siz[ch[o][0]] + 1, o = ch[o][1]; } } inline int findpre(int &root, int v) { int a = 0, b = 0; Split(root, v - 1, a, b); int res = kth(a, siz[a]); root = Merge(a, b); return val[res]; } inline int findnxt(int &root, int v) { int a = 0, b = 0; Split(root, v, a, b); int res = kth(b, 1); root = Merge(a, b); return val[res]; } signed main() { srand((unsigned)20020315); insert(rt[0], -2147483647), insert(rt[0], 2147483647); n = read(); for (reg int i = 1 ; i <= n ; i ++) { int lst = read(), opt = read(), x = read(); rt[i] = rt[lst]; if (opt == 1) insert(rt[i], x); else if (opt == 2) delet(rt[i], x); else if (opt == 3) printf("%d\n", rnk(rt[i], x)); else if (opt == 4) printf("%d\n", val[kth(rt[i], x + 1)]); else if (opt == 5) printf("%d\n", findpre(rt[i], x)); else printf("%d\n", findnxt(rt[i], x)); } return 0; }