P5076 【深基16.例7】普通二叉树(简化版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include<cstdio>
#include<algorithm>
using namespace std;
#define re register
const int MAXn = 1e4;
const int INF = 2147483647;

template <class T>
inline void read(T &a) {
register char c;for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar());register bool f = c == '-';register T s = f ? 0 : c - '0';for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) {s = (s << 3) + (s << 1) + c - '0';}a = f ? -s : s;
}

struct Node {
int l, r, siz, cnt, val;
};
Node nd[MAXn + 10];
int cnt;

void Insert(int id, int val) {
++nd[id].siz;
if (nd[id].val == val) {
++nd[id].cnt;
} else if (nd[id].val < val) {
if (!nd[id].r) {
nd[++cnt].val = val;
nd[id].r = cnt;
}
Insert(nd[id].r, val);
} else {
if (!nd[id].l) {
nd[++cnt].val = val;
nd[id].l = cnt;
}
Insert(nd[id].l, val);
}
}
int ValtoRank(int id, int val) {
if (!id) {
return 1;
}
if (nd[id].val == val) {
return nd[nd[id].l].siz + 1;
} else if (nd[id].val < val) {
return nd[nd[id].l].siz + nd[id].cnt + ValtoRank(nd[id].r, val);
} else {
return ValtoRank(nd[id].l, val);
}
}
int RanktoVal(int id, int rank) {
if (!id) {
return -123456789;
}
if (rank <= nd[nd[id].l].siz) {
return RanktoVal(nd[id].l, rank);
} else if (rank > nd[nd[id].l].siz + nd[id].cnt) {
return RanktoVal(nd[id].r, rank - nd[nd[id].l].siz - nd[id].cnt);
} else {
return nd[id].val;
}
}
int EvaPreVal(int id, int val) {
if (!id) {
return -INF;
}
if (nd[id].val >= val) {
return EvaPreVal(nd[id].l, val);
} else {
return max(nd[id].val, EvaPreVal(nd[id].r, val));
}
}
int EvaNexVal(int id, int val) {
if (!id) {
return INF;
}
if (nd[id].val <= val) {
return EvaNexVal(nd[id].r, val);
} else {
return min(nd[id].val, EvaNexVal(nd[id].l, val));
}
}

int root = 1, n, opt, x;
int main() {
read(n);
nd[1].cnt = 1; nd[1].l = 2; nd[1].siz = 2; nd[1].val = INF;
nd[2].cnt = 1; nd[2].siz = 1; nd[2].val = -INF;
cnt += 2;
for (re int i = 1; i <= n; ++i) {
read(opt), read(x);
switch (opt) {
case 1:
printf("%d\n", ValtoRank(root, x) - 1);
break;
case 2:
printf("%d\n", RanktoVal(root, x + 1));
break;
case 3:
printf("%d\n", EvaPreVal(root, x));
break;
case 4:
printf("%d\n", EvaNexVal(root, x));
break;
case 5:
Insert(root, x);
break;
}
}
}