-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathORDERSET - Treap.cpp
executable file
·130 lines (112 loc) · 2.28 KB
/
ORDERSET - Treap.cpp
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
/*
In this problem, you have to maintain a dynamic set of numbers which support the two fundamental operations
INSERT(S,x): if x is not in S, insert x into S
DELETE(S,x): if x is in S, delete x from S
and the two type of queries
K-TH(S) : return the k-th smallest element of S
COUNT(S,x): return the number of elements of S smaller than x
*/
#include <bits/stdc++.h>
using namespace std;
struct Treap{
struct Node{
int val, prio, qtd;
Node *L, *R;
Node(){}
Node(int val): val(val), prio(rand()), qtd(1), L(NULL), R(NULL){}
} *root;
Treap(): root(NULL){ srand(time(NULL)); }
int qtd(Node *node){
return node? node->qtd : 0;
}
void upd(Node *node){
if(!node) return;
node->qtd = qtd(node->L) + 1 + qtd(node->R);
}
Node *merge(Node *a, Node *b){
if(!a) return b;
if(!b) return a;
if(a->prio >= b->prio){
a->R = merge(a->R, b);
upd(a);
return a;
}else{
b->L = merge(a, b->L);
upd(b);
return b;
}
}
void split(Node *node, int val, Node *&a, Node *&b){
if(!node){
a = b = NULL;
return;
}
Node *tmp;
if(node->val <= val){
split(node->R, val, tmp, b);
a = node;
a->R = tmp;
upd(a);
}else{
split(node->L, val, a, tmp);
b = node;
b->L = tmp;
upd(b);
}
}
void insert(int val){
Node *a, *b;
split(root, val, a, b);
root = merge(merge(a, new Node(val)), b);
}
void erase(int val){
Node *a, *b, *c;
split(root, val, a, c);
split(a, val - 1, a, b);
root = merge(a, c);
delete b;
b = NULL;
}
int count(int val){
Node *a, *b;
split(root, val - 1, a, b);
int ret = qtd(a);
root = merge(a, b);
return ret;
}
int kth(Node *node, int k){
int pos = qtd(node->L) + 1;
if(pos == k) return node->val;
if(pos > k) return kth(node->L, k);
return kth(node->R, k - pos);
}
int kth(int k){
return kth(root, k);
}
} treap;
int main(){
int q;
scanf("%d", &q);
unordered_map<int, bool> has;
while(q--){
char type; int x;
scanf(" %c %d", &type, &x);
if(type == 'I'){
if(!has[x]){
has[x] = true;
treap.insert(x);
}
}else if(type == 'D'){
if(has[x]){
has[x] = false;
treap.erase(x);
}
}else if(type == 'K'){
if(x <= treap.qtd(treap.root)) printf("%d\n", treap.kth(x));
else printf("invalid\n");
}else{
printf("%d\n", treap.count(x));
}
}
return 0;
}