rt,指针版的 fhq-treap,空指针的都查过了 /kel
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
mt19937 eng(time(0));
uniform_int_distribution<int> dist;
typedef struct node {
int w, val, s;
node *l, *r;
node(int val = 0, int s = 0) :
val(val), s(s), l(nullptr), r(nullptr), w(dist(eng)) {}
~node() { delete l, r; }
int size() {
if (this) return s;
return 0;
}
void pushup() {
s = l->size() + r->size() + 1;
}
} *nodeptr; nodeptr rt;
void split(nodeptr p, int val, nodeptr &x, nodeptr &y) {
if (!p) return x = y = nullptr, void();
if (p->val <= val) x = p, split(x->r, val, x->r, y);
else y = p, split(y->l, val, x, y->l); p->pushup();
}
nodeptr merge(nodeptr x, nodeptr y) {
if (!x || !y) return x == nullptr ? y : x;
if (x->w < y->w) return x->r = merge(x->r, y), x->pushup(), x;
return y->l = merge(x, y->l), y->pushup(), y;
}
inline
void insert(int val) {
nodeptr l = nullptr, r = nullptr; split(rt, val, l, r);
rt = merge(merge(l, new node(val, 1)), r);
}
inline
void erase(int val) {
nodeptr l = nullptr, r = nullptr, p = nullptr;
split(rt, val, l, r), split(l, val - 1, l, p);
rt = merge(merge(l, merge(p->l, p->r)), r);
}
inline
int rnk(int val) {
int ans; nodeptr l = nullptr, r = nullptr;
split(rt, val - 1, l, r), ans = l->size();
return rt = merge(l, r), ans + 1;
}
inline
int kth(int k) {
for (nodeptr p = rt; p;) {
if (p->l->size() >= k) p = p->l;
else if (p->l->size() + 1 == k) return p->val;
else k -= p->l->size() + 1, p = p->r;
}
return -1;
}
inline
int find(int val, int f) {
nodeptr l = nullptr, r = nullptr, p = nullptr;
split(rt, val - f, l, r);
if (f) for (p = l; p->r; p = p->r);
else for (p = r; p->l; p = p->l);
return rt = merge(l, r), p->val;
}
int n;
int main() {
scanf("%d", &n);
for (int opt, x; n--;) {
scanf("%d%d", &opt, &x);
switch (opt) {
case 1 : insert(x); break;
case 2 : erase(x); break;
case 3 : printf("%d\n", rnk(x)); break;
case 4 : printf("%d\n", kth(x)); break;
case 5 : printf("%d\n", find(x, 1)); break;
case 6 : printf("%d\n", find(x, 0)); break;
}
}
}