-
Notifications
You must be signed in to change notification settings - Fork 2
/
treap key + val.cpp
125 lines (109 loc) · 1.83 KB
/
treap key + val.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
class Treap {
public:
typedef struct _node {
int key;
int cnt;
int prior;
int val;
_node* l;
_node* r;
_node(int key, int val) :key(key), val(val), l(nullptr), r(nullptr), cnt(1) { prior = (rand() << 16) | rand(); }
void push() {
}
void recalc() {
cnt = 1 + Cnt(l) + Cnt(r);
}
static int Cnt(_node* v) {
if (!v)
return 0;
return v->cnt;
}
}*node;
static int Cnt(node v) {
if (!v)
return 0;
return v->cnt;
}
node root;
size_t Size;
node merge(node l, node r) {
if (!l)
return r;
if (!r)
return l;
if (l->prior < r->prior) {
l->push();
l->r = merge(l->r, r);
l->recalc();
return l;
}
else {
r->push();
r->l = merge(l, r->l);
r->recalc();
return r;
}
}
void split(node v, int key, node& l, node& r) {
l = r = nullptr;
if (!v)
return;
v->push();
if (v->key < key) {
l = v;
split(l->r, key, l->r, r);
l->recalc();
}
else {
r = v;
split(r->l, key, l, r->l);
r->recalc();
}
}
public:
Treap() {
root = nullptr;
Size = 0;
}
size_t size() const {
return Size;
}
node get_min() const {
node v = root;
if (!v) {
throw runtime_error("Treap is empty");
}
while (v->l) {
v = v->l;
}
return v;
}
node get_max() const {
node v = root;
if (!v) {
throw runtime_error("Treap is empty");
}
while (v->r) {
v = v->r;
}
return v;
}
void insert(int key, int val) {
node l = nullptr, r = nullptr;
split(root, key, l, r);
node cur_node = new _node(key, val);
root = merge(merge(l, cur_node), r);
++Size;
}
node operator [] (int key) {
node l = nullptr, m = nullptr, r = nullptr;
split(root, key, l, r);
split(r, key + 1, m, r);
if (m == nullptr) {
throw runtime_error("IndexTreapOutOfBound");
}
root = merge(merge(l, m), r);
return m;
}
};
typedef Treap::node Node;