- 玄关求调
普通平衡树 ——FHQTreap
- @ 2025-8-21 15:09:42
// FHQ-Treap
#include <cstdio>
#include <cstdlib>
#define lc son[p][0]
#define rc son[p][1]
const int N = 1e5 + 5;
int n, root, idx;
int val[N], son[N][2], pri[N], siz[N];
void up(int p) { siz[p] = siz[lc] + siz[rc] + 1; }
void split(int p, int v, int &l, int &r) {
if (!p) {
l = r = 0;
return;
}
if (val[p] <= v) {
l = p;
up(p);
split(rc, v, rc, v);
} else {
r = p;
up(p);
split(lc, v, l, lc);
}
}
int merge(int l, int r) {
if (!l || !r) return l + r;
if (pri[l] > pri[r]) {
son[l][1] = merge(son[l][1], r);
up(l);
up(r);
return l;
} else {
son[r][0] = merge(l, son[r][0]);
up(l);
up(r);
return r;
}
}
void insert(int v) {
int p = ++idx, l, r;
pri[p] = rand();
val[p] = v;
siz[p] = 1;
root = merge(merge(l, p), r);
}
void Delete(int v) {
int l, r, mid;
split(root, v, l, r);
split(l, v - 1, l, mid);
mid = merge(son[mid][0], son[mid][1]);
root = merge(merge(l, mid), r);
}
int rnk(int v) {
int l, r;
split(root, v - 1, l, r);
int res = siz[l] + 1;
root = merge(l, r);
return res;
}
int kth(int p, int v) {
if(siz[lc] >= v) return kth(lc, v);
if(siz[lc] + 1 == v) return val[p];
return kth(rc, v - siz[lc] - 1);
}
int getpre(int v) {
int l, r;
split(root, v - 1, l, r);
int res = kth(l, siz[l]);
root = merge(l, r);
return res;
}
int getnext(int v) {
int l, r;
split(root, v, l, r);
int res = kth(r, 1);
root = merge(l, r);
return res;
}
int main()
{
scanf("%d", &n);
while (n--) {
int opt, x;
scanf("%d %d", &opt, &x);
switch (opt) {
case 1 : insert(x); break;
case 2 : Delete(x); break;
case 3 : printf("%d\n", rnk(x)); break;
case 4 : printf("%d\n", kth(root, x)); break;
case 5 : printf("%d\n", getpre(x)); break;
case 6 : printf("%d\n", getnext(x)); break;
}
}
return 0;
}
0 条评论
目前还没有评论...