-
Notifications
You must be signed in to change notification settings - Fork 2
/
treap implicit key with parents.cpp
140 lines (123 loc) · 2.1 KB
/
treap implicit key with parents.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
131
132
133
134
135
136
137
138
139
140
class Treap {
public:
typedef struct _node {
int cnt;
int prior;
int val;
_node* l;
_node* r;
_node *p;
int pType;
_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);
if (l) {
l->p = this;
}
if (r) {
r->p = this;
}
p = nullptr;
}
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) {
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;
}
int get_index(node v) {
if (!v) {
throw runtime_error("No such node in the treap");
}
int res = Cnt(v->l);
while (v->p) {
if (v->p->r == v) {
res += Cnt(v->p->l) + 1;
}
v = v->p;
}
return res;
}
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;