-
Notifications
You must be signed in to change notification settings - Fork 2
/
treap implicit key.cpp
122 lines (101 loc) · 1.81 KB
/
treap implicit key.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
class Treap {
public:
typedef struct _node {
int cnt;
int prior;
int val;
_node* l;
_node* r;
_node(int val) :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 idx, node& l, node& r) {
l = r = nullptr;
if (!v)
return;
v->push();
if (Cnt(v->l) < idx) {
l = v;
split(l->r, idx - Cnt(v->l) - 1, l->r, r);
l->recalc();
}
else {
r = v;
split(r->l, idx, l, r->l);
r->recalc();
}
}
public:
Treap() {
root = nullptr;
Size = 0;
}
size_t size() const {
return Size;
}
void insert(int idx, int val) { //insert at the idx - position
node l = nullptr, r = nullptr;
split(root, idx, l, r);
node cur_node = new _node(val);
root = merge(merge(l, cur_node), r);
++Size;
}
void erase(int idx) {
node l = nullptr, m = nullptr, r = nullptr;
split(root, idx, l, r);
split(r, 1, m, r);
root = merge(l, r);
--Size;
}
void push_back(int val) {
return insert(Size, val);
}
void push_front(int val) {
return insert(0, val);
}
node operator [] (int idx) {
node l = nullptr, m = nullptr, r = nullptr;
split(root, idx, l, r);
split(r, 1, m, r);
if (m == nullptr) {
throw runtime_error("IndexTreapOutOfBound");
}
root = merge(merge(l, m), r);
return m;
}
};
typedef Treap::node Node;