TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
treap.cpp
Go to the documentation of this file.
1
20#include <array>
21#include <cassert>
22#include <cstdint>
23#include <iostream>
24
29namespace data_structures {
35namespace treap {
36const int maxNode = 1e5 + 5;
40struct Treap {
41 int root = 0;
42 int treapCnt = 0;
43 std::array<int, maxNode> key = {};
44 std::array<int, maxNode> priority = {};
45 std::array<std::array<int, 2>, maxNode> childs = {
46 {}};
49 std::array<int, maxNode> cnt =
50 {};
51 std::array<int, maxNode> size = {};
55 Treap() : treapCnt(1) {
56 priority[0] = INT32_MAX;
57 size[0] = 0;
58 }
63 void update(int x) {
64 size[x] = size[childs[x][0]] + cnt[x] + size[childs[x][1]];
65 }
71 void rotate(int &x, int t) {
72 int y = childs[x][t];
73 childs[x][t] = childs[y][1 - t];
74 childs[y][1 - t] = x;
75 // The rotation will only change itself and its son nodes
76 update(x);
77 update(y);
78 x = y;
79 }
85 void _insert(int &x, int k) {
86 if (x) {
87 if (key[x] == k) {
88 cnt[x]++;
89 } // If the node already exists, the number of copies is ++
90 else {
91 int t = (key[x] < k); // Insert according to BST properties
92 _insert(childs[x][t], k);
93 // After insertion, the heap properties are retained by rotation
94 if (priority[childs[x][t]] < priority[x]) {
95 rotate(x, t);
96 }
97 }
98 } else { // Create a new node
99 x = treapCnt++;
100 key[x] = k;
101 cnt[x] = 1;
102 priority[x] = rand(); // Random priority
103 childs[x][0] = childs[x][1] = 0;
104 }
105 update(x);
106 }
112 void _erase(int &x, int k) {
113 if (key[x] == k) {
114 if (cnt[x] > 1) {
115 cnt[x]--;
116 } // If the node has more than one copy, the number of copies --
117 else {
118 if (childs[x][0] == 0 && childs[x][1] == 0) {
119 x = 0;
120 return;
121 } // If there are no children, delete and return
122 // Otherwise, we need to rotate the sons and delete them
123 // recursively
124 int t = (priority[childs[x][0]] > priority[childs[x][1]]);
125 rotate(x, t);
126 _erase(x, k);
127 }
128 } else { // Find the target value based on BST properties
129 _erase(childs[x][key[x] < k], k);
130 }
131 update(x);
132 }
139 int _get_k_th(int &x, int k) {
140 if (k <= size[childs[x][0]]) {
141 return _get_k_th(childs[x][0], k);
142 }
143 k -= size[childs[x][0]] + cnt[x];
144 if (k <= 0) {
145 return key[x];
146 }
147 return _get_k_th(childs[x][1], k);
148 }
155 int _get_rank(int x, int k) {
156 if (!x) {
157 return 0;
158 }
159 if (k == key[x]) {
160 return size[childs[x][0]] + 1;
161 } else if (k < key[x]) {
162 return _get_rank(childs[x][0], k);
163 } else {
164 return size[childs[x][0]] + cnt[x] + _get_rank(childs[x][1], k);
165 }
166 }
172 int get_predecessor(int k) {
173 int x = root, pre = -1;
174 while (x) {
175 if (key[x] < k) {
176 pre = key[x], x = childs[x][1];
177 } else {
178 x = childs[x][0];
179 }
180 }
181 return pre;
182 }
188 int get_next(int k) {
189 int x = root, next = -1;
190 while (x) {
191 if (key[x] > k) {
192 next = key[x], x = childs[x][0];
193 } else {
194 x = childs[x][1];
195 }
196 }
197 return next;
198 }
203 void insert(int k) { _insert(root, k); }
208 void erase(int k) { _erase(root, k); }
214 int get_k_th(int k) { return _get_k_th(root, k); }
220 int get_rank(int k) { return _get_rank(root, k); }
221};
222} // namespace treap
223} // namespace data_structures
224
229static void test() {
231
232 mTreap.insert(1);
233 mTreap.insert(2);
234 mTreap.insert(3);
235 assert(mTreap.get_k_th(2) == 2);
236 mTreap.insert(4);
237 mTreap.insert(5);
238 mTreap.insert(6);
239 assert(mTreap.get_next(4) == 5);
240 mTreap.insert(7);
241 assert(mTreap.get_predecessor(7) == 6);
242 mTreap.erase(4);
243 assert(mTreap.get_k_th(4) == 5);
244 assert(mTreap.get_rank(5) == 4);
245 mTreap.insert(10);
246 assert(mTreap.get_rank(10) == 7);
247 assert(mTreap.get_predecessor(10) == 7);
248
249 std::cout << "All tests have successfully passed!\n";
250}
255int main() {
256 test(); // run self-test implementations
257 return 0;
258}
const int maxNode
maximum number of nodes
Definition treap.cpp:36
for IO operations
Struct representation of the treap.
Definition treap.cpp:40
int treapCnt
Total number of current nodes in the treap.
Definition treap.cpp:42
int root
root of the treap
Definition treap.cpp:41
std::array< int, maxNode > key
Node identifier.
Definition treap.cpp:43
Treap()
Initialization.
Definition treap.cpp:55
void insert(int k)
Insert element (External method)
Definition treap.cpp:203
void _insert(int &x, int k)
Insert a value into the specified subtree (internal method)
Definition treap.cpp:85
void rotate(int &x, int t)
Rotate without breaking the property of BST.
Definition treap.cpp:71
int get_next(int k)
Get the successor node of element k.
Definition treap.cpp:188
std::array< int, maxNode > priority
Random priority.
Definition treap.cpp:44
int _get_rank(int x, int k)
Query the rank of specified element (internal method)
Definition treap.cpp:155
void erase(int k)
Erase element (External method)
Definition treap.cpp:208
void update(int x)
Update the subtree size of the node.
Definition treap.cpp:63
int get_k_th(int k)
Get the KTH largest value (External method)
Definition treap.cpp:214
int get_predecessor(int k)
Get the predecessor node of element k.
Definition treap.cpp:172
std::array< std::array< int, 2 >, maxNode > childs
Definition treap.cpp:45
int get_rank(int k)
Get the rank of specified element (External method)
Definition treap.cpp:220
int _get_k_th(int &x, int k)
Find the KTH largest value (internal method)
Definition treap.cpp:139
void _erase(int &x, int k)
Erase a value from the specified subtree (internal method)
Definition treap.cpp:112
std::array< int, maxNode > size
The number of copies per node.
Definition treap.cpp:51
std::array< int, maxNode > cnt
Maintains the subtree size for ranking query.
Definition treap.cpp:49
static void test()
Self-test implementations.
Definition treap.cpp:229
int main()
Main function.
Definition treap.cpp:255