fhq treap
祭学会fhq treap
下次有需要再补上 先存个模板
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int root, n, a, x, y, z, op, Size, siz[N], val[N], rd[N], ch[N][3];
inline int read() {
char ch; bool f = false; int res = 0;
while (((ch = getchar()) < '0' || ch > '9') && ch != '-');
if (ch == '-') f = true; else res = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + (ch ^ 48);
return f? ~res + 1 : res;
}
inline void pushup (int x) {
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
}
inline int New (int x) {
siz[++Size] = 1, val[Size] = x, rd[Size] = rand();
return Size;
}
void split (int p, int &x, int &y, int a) {
if (p == 0) x = y = 0;
else {
if (val[p] <= a) {
x = p;
split(ch[p][1], ch[p][1], y, a);
}
else {
y = p;
split(ch[p][0], x, ch[p][0], a);
}
pushup(p);
}
}
int merge (int a, int b) {
if (a == 0 || b == 0)
return a + b;
if (rd[a] < rd[b]) {
ch[a][1] = merge(ch[a][1], b);
pushup(a);
return a;
}
else {
ch[b][0] = merge(a, ch[b][0]);
pushup(b);
return b;
}
}
inline int kth (int x, int a) {
while (true) {
if (a <= siz[ch[x][0]])
x = ch[x][0];
else if (a == siz[ch[x][0]] + 1)
return x;
else a -= siz[ch[x][0]] + 1, x = ch[x][1];
}
}
int main() {
srand(time(0));
n = read();
for (int i = 1; i <= n; i++) {
op = read(), a = read();
if (op == 1) { // insert
split(root, x, y, a);
root = merge(merge(x, New(a)), y);
}
else if (op == 2) { // delete
split(root, x, z, a);
split(x, x, y, a - 1);
y = merge(ch[y][0], ch[y][1]);
root = merge(merge(x, y), z);
}
else if (op == 3) { // rank
split(root, x, y, a - 1);
printf("%d\n", siz[x] + 1);
root = merge(x, y);
}
else if (op == 4) { // xth
printf("%d\n", val[kth(root, a)]);
}
else if (op == 5) { // pred
split(root, x, y, a - 1);
printf("%d\n", val[kth(x, siz[x])]);
root = merge(x, y);
}
else if (op == 6) { // succ
split(root, x, y, a);
printf("%d\n", val[kth(y, 1)]);
root = merge(x, y);
}
}
return 0;
}