rt,过不去样例,总会有几个节点的 size 莫名其妙变成0
#include <bits/stdc++.h>
#include <cassert>
#define BAR cout << "*******\n";
#define fst first
#define snd second
#define INFILE(x) freopen(x, "r", stdin)
#define OUTFILE(x) freopen(x, "w", stdout)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
using namespace std;
using ll = long long;
using ul = unsigned long long;
using ui = unsigned int;
using db = double;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pll = pair<ll, ll>;
static mt19937 rng;
template <typename T, int N> struct treap {
struct node {
int l, r, size;
T val;
unsigned rnd;
void init(T v) {
val = v;
l = r = 0;
size = 1;
rnd = rng();
}
} nodes[N];
int root = 0, tot = 0;
void push_up(int node) {
nodes[node].size =
nodes[nodes[node].l].size + nodes[nodes[node].r].size;
}
void split(int node, T v, int &x, int &y) {
if (!node) {
x = y = 0;
return;
}
if (v < nodes[node].val) {
y = node;
split(nodes[node].l, v, x, nodes[node].l);
} else {
x = node;
split(nodes[node].r, v, nodes[node].r, y);
}
push_up(node);
assert(nodes[node].size || !node);
}
int merge(int x, int y) {
if (!x) return y;
if (!y) return x;
if (nodes[x].rnd > nodes[y].rnd) {
nodes[x].r = merge(nodes[x].r, y);
push_up(x);
assert(nodes[x].size);
return x;
} else {
nodes[y].l = merge(x, nodes[y].l);
push_up(y);
assert(nodes[y].size);
return y;
}
}
void insert(T v) {
nodes[++tot].init(v);
if (!root) {
root = tot;
return;
}
int x, y;
split(root, v, x, y);
int z = tot;
root = merge(merge(x, z), y);
}
void del(T v) {
int x, y, z;
split(root, v, x, z);
split(x, v - 1, x, y);
y = merge(nodes[y].l, nodes[y].r);
root = merge(merge(x, y), z);
}
int rank(T v) {
int x, y;
split(root, v - 1, x, y);
int res = nodes[x].size + 1;
root = merge(x, y);
return res;
}
T get_nth(int node, int n) {
int lsz = nodes[nodes[node].l].size + 1;
if (lsz == n) {
return nodes[node].val;
} else if (n < lsz) {
return get_nth(nodes[node].l, n);
} else {
return get_nth(nodes[node].r, n - lsz);
}
}
T nth(int n) { return get_nth(root, n); }
T prec(T v) {
int x, y;
split(root, v - 1, x, y);
T res = get_nth(x, nodes[x].size);
root = merge(x, y);
return res;
}
T succ(T v) {
int x, y;
split(root, v, x, y);
T res = get_nth(y, 1);
root = merge(x, y);
return res;
}
};
constexpr int max_n = 1e5 + 10;
treap<int, max_n> tree;
int main() {
// INFILE("IOFile/P3369_6.in");
ios::sync_with_stdio(0);
cin.tie(0);
int op, k, T;
cin >> T;
while (T--) {
cin >> op >> k;
switch (op) {
case 1:
tree.insert(k);
break;
case 2:
tree.del(k);
break;
case 3:
cout << tree.rank(k) << '\n';
break;
case 4:
cout << tree.nth(k) << '\n';
break;
case 5:
cout << tree.prec(k) << '\n';
break;
case 6:
cout << tree.succ(k) << '\n';
break;
default:
break;
}
}
return 0;
}