0%

Luogu P3369 (Treap模板)

题目链接

平衡树板题,用 Treap 实现

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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 100005;

int n, cnt;

struct Treap{
Treap *L, *R;
int fix, val, size;
void Init() { L = R = NULL; }
inline int lsize() { return L ? L->size : 0; }
inline int rsize() { return R ? R->size : 0; }
} Node[N], *root;

Treap * NewNode() {
Node[cnt].Init();
return Node + (cnt++);
}

void Recount(Treap * &p) {
p->size = p->lsize() + p->rsize() + 1;
}

void Treap_R_Rot(Treap *&a) {
Treap *b = a->L;
a->L = b->R;
b->R = a;
a = b;
Recount(a->R);
Recount(a);
}

void Treap_L_Rot(Treap *&a) {
Treap *b = a->R;
a->R = b->L;
b->L = a;
a = b;
Recount(a->L);
Recount(a);
}

void Treap_insert(Treap *&p, int val) {
if(p == NULL) {
p = NewNode();
p->val = val;
p->size = 1;
p->fix = rand();
} else if(val <= p->val) {
p->size++;
Treap_insert(p->L, val);
if(p->L->fix < p->fix) Treap_R_Rot(p);
} else {
p->size++;
Treap_insert(p->R, val);
if(p->R->fix < p->fix) {
Treap_L_Rot(p);
}
}
}

void Treap_Del(Treap * &p, int val) {
if(val == p->val) {
if(!p->L || !p->R) {
if (p->L) p = p->L;
else p = p->R;
} else if(p->L->fix < p->R->fix) {
Treap_R_Rot(p);
p->size--;
Treap_Del(p->R, val);
} else {
Treap_L_Rot(p);
p->size--;
Treap_Del(p->L, val);
}
} else if(val < p->val) {
p->size--;
Treap_Del(p->L, val);
} else {
p->size--;
Treap_Del(p->R, val);
}
}

int Treap_Rank(Treap *p, int val) {
if(!p) return 0;
if(val > p->val) return p->lsize() + Treap_Rank(p->R, val) + 1;
else return Treap_Rank(p->L, val);
}

int Treap_Find(Treap *p, int rank) {
if(p->lsize()+1 == rank)
return p->val;
if(p->lsize()+1 > rank)
return Treap_Find(p->L, rank);
else
return Treap_Find(p->R, rank - p->lsize() - 1);
}

int Treap_pre(Treap *p, int val, int now) {
if(!p) return now;
if(p->val < val)
return Treap_pre(p->R, val, p->val);
return Treap_pre(p->L, val, now);
}

int Treap_suc(Treap *p, int val, int now) {
if(!p) return now;
if(p->val > val) return Treap_suc(p->L, val, p->val);
return Treap_suc(p->R, val, now);
}

int main() {
cin >> n;
while(n--) {
int opt, x;
scanf("%d%d", &opt, &x);
if(opt == 1) Treap_insert(root, x);
else if(opt == 2) Treap_Del(root, x);
else if(opt == 3) printf("%d\n", Treap_Rank(root, x) + 1);
else if(opt == 4) printf("%d\n", Treap_Find(root, x));
else if(opt == 5) printf("%d\n", Treap_pre(root, x, root->val));
else if(opt == 6) printf("%d\n", Treap_suc(root, x, root->val));
}

return 0;
}
求大佬赏个饭