对着 LYD 蓝书抄的,应该是一样的,求大佬帮忙看看 Orz
#include <iostream>
#include <stdio.h>
using namespace std;
const int S = 1e5 + 5;
const int I = 1 << 30;
struct N {
int l, r;
int val, lev;
int cnt, siz;
} a[S];
int tot, root, q;
int newnode(int val) {
a[++tot].val = val;
a[tot].lev = rand();
a[tot].cnt = a[tot].siz = 1;
return tot;
}
void pushup(int p) {
a[p].siz = a[a[p].l].siz + a[a[p].r].siz + a[p].cnt;
}
void build() {
newnode(-I);
newnode(I);
root = 1;
a[1].r = 2;
pushup(root);
}
int getRankByVal(int p, int val) {
if (p == 0) {
return 0;
}
if (val == a[p].val) {
return a[a[p].l].siz + 1;
}
if (val < a[p].val) {
return getRankByVal(a[p].l, val);
}
return getRankByVal(a[p].r, val) + a[a[p].l].siz + a[p].cnt;
}
int getValByRank(int p, int rank) {
if (p == 0) {
return I;
}
if (a[a[p].l].siz >= rank) {
return getValByRank(a[p].l, rank);
}
if (a[a[p].l].siz + a[p].cnt >= rank) {
return a[p].val;
}
return getValByRank(a[p].r, rank - a[a[p].l].siz - a[p].cnt);
}
void zig(int &p) {
int q = a[p].l;
a[p].l = a[q].r, a[q].r = p, p = q;
pushup(a[p].r);
pushup(p);
}
void zag(int &p) {
int q = a[p].r;
a[p].r = a[q].l, a[q].l = p, p = q;
pushup(a[p].l);
pushup(p);
}
void insert(int &p, int val) {
if (p == 0) {
p = newnode(val);
return;
}
if (val == a[p].val) {
a[p].cnt++;
pushup(p);
return;
}
if (val < a[p].val) {
insert(a[p].l, val);
if (a[p].lev < a[a[p].l].lev) {
zig(p);
}
} else {
insert(a[p].r, val);
if (a[p].lev < a[a[p].r].lev) {
zag(p);
}
}
pushup(p);
}
int getPre(int val) {
int ans = 1; // a[1].val == -I
int p = root;
while (p) {
if (val == a[p].val) {
if (a[p].l > 0) {
p = a[p].l;
while (a[p].r > 0) {
p = a[p].r;
}
ans = p;
}
break;
}
if (a[p].val < val && a[p].val > a[ans].val) {
ans = p;
}
if (val < a[p].val) {
p = a[p].l;
} else {
p = a[p].r;
}
}
return a[ans].val;
}
int getNext(int val) {
int ans = 2; // a[2].val == I
int p = root;
while (p) {
if (val == a[p].val) {
if (a[p].r > 0) {
p = a[p].r;
while (a[p].l > 0) {
p = a[p].l;
}
ans = p;
}
break;
}
if (a[p].val > val && a[p].val < a[ans].val) {
ans = p;
}
if (val < a[p].val) {
p = a[p].l;
} else {
p = a[p].r;
}
}
return a[ans].val;
}
void remove(int &p, int val) {
if (p == 0) {
return;
}
if (val == a[p].val) {
if (a[p].cnt > 1) {
a[p].cnt--;
pushup(p);
return;
}
if (a[p].l || a[p].r) {
if (a[p].r == 0 || a[a[p].l].lev > a[a[p].r].lev) {
zig(p);
remove(a[p].r, val);
} else {
zag(p);
remove(a[p].l, val);
}
pushup(p);
} else {
p = 0;
}
return;
}
if (val < a[p].val) {
remove(a[p].l, val);
} else {
remove(a[p].r, val);
}
pushup(p);
}
int main() {
build();
cin >> q;
while (q--) {
int op, x;
scanf("%d%d", &op, &x);
switch (op) {
case 1: {
insert(root, x);
break;
}
case 2: {
remove(root, x);
break;
}
case 3: {
printf("%d\n", getRankByVal(root, x) - 1);
break;
}
case 4: {
printf("%d\n", getValByRank(root, x + 1));
break;
}
case 5: {
printf("%d\n", getPre(x));
break;
}
case 6: {
printf("%d\n", getNext(x));
break;
}
}
}
return 0;
}