平衡树模板题求调,用的splay,调完就能获得关注一枚。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7, INF = 1e8;
struct Splay {
int s[2], v, p, cnt, siz;
};
Splay tr[N];
int n, root = 0, idx = 0, opt, X;
void pushup(int u) {
tr[u].siz = tr[tr[u].s[0]].siz + tr[tr[u].s[1]].siz + tr[u].cnt;
}
int Get(int x) {
return tr[tr[x].p].s[1] == x;
}
void rotate(int x) {
int y = tr[x].p, z = tr[y].p;
int kx = Get(x), ky = Get(y);
tr[z].s[ky] = x;
tr[x].p = z;
tr[y].s[kx] = tr[x].s[kx ^ 1];
tr[tr[x].s[kx ^ 1]].p = y;
tr[x].s[kx ^ 1] = y;
tr[y].p = x;
pushup(y), pushup(x);
return;
}
void splay(int x, int k) {
while (tr[x].p != k) {
int y = tr[x].p, z = tr[y].p;
if (z != k) {
if (Get(x) == Get(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
if(!k) root = x;
return;
}
void insert(int v) {
int u = root, p = 0;
while (u) {
if (tr[u].v == v) {
tr[u].cnt++;
splay(u, 0);
return;
}
p = u;
u = tr[u].s[v > tr[u].v];
}
u = ++idx;
if (p) tr[p].s[v > tr[p].v] = u;
tr[u].p = p;
tr[u].v = v;
tr[u].siz = 1;
splay(u, 0);
return;
}
void find(int x) {
if (!root) return;
int u = root;
while (tr[u].s[x > tr[u].v] && tr[u].v != x) u = tr[u].s[x > tr[u].v];
splay(u, 0);
return;
}
int Last(int x) {
find(x);
if (tr[root].v < x) return root;
int u = tr[root].s[0];
while (tr[u].s[1]) u = tr[u].s[1];
splay(u, 0);
return u;
}
int Next(int x) {
find(x);
if (tr[root].v > x) return root;
int u = tr[root].s[1];
while (tr[u].s[0]) u = tr[u].s[0];
splay(u, 0);
return u;
}
void Delete(int x) {
int L = Last(x), N = Next(x);
splay(L, 0), splay(N, L);
int d = tr[N].s[0];
if (tr[d].cnt > 1) tr[d].cnt--, splay(d, 0);
else tr[N].s[0] = 0;
pushup(N), pushup(L);
return;
}
int get_rank(int x) {
find(x);
if (tr[root].v < x) return tr[root].cnt + tr[tr[root].s[0]].siz;
return tr[tr[root].s[0]].siz;
}
int Kth(int k) {
int u = root;
while (1) {
// cout << 1 << ' ';
if (k <= tr[tr[u].s[0]].siz && tr[u].s[0])
u = tr[u].s[0];
else if (k > tr[tr[u].s[0]].siz + tr[u].cnt) {
k -= tr[tr[u].s[0]].siz + tr[u].cnt, u = tr[u].s[1];
// cout << tr[u].cnt;
}
else {
// cout << 1;
splay(u, 0);
return u;
}
}
return 114514;
}
int main() {
insert(INF), insert(-INF);
cin >> n;
while (n--) {
cin >> opt >> X;
if (opt == 1) insert(X);
else if (opt == 2) Delete(X);
else if (opt == 3) cout << get_rank(X) << '\n';
else if (opt == 4) cout << tr[Kth(X + 1)].v << '\n';
else if (opt == 5) cout << tr[Last(X)].v << '\n';
else cout << tr[Next(X)].v << '\n';
}
return 0;
}