Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit 61ae51f

Browse files
committed
ProtovEB.cpp
1 parent e132c81 commit 61ae51f

File tree

2 files changed

+258
-0
lines changed

2 files changed

+258
-0
lines changed

ProtovEB.cpp

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_ProtovEB
22+
#endif
23+
24+
#ifndef FUNC_ProtovEB
25+
#define FUNC_ProtovEB
26+
27+
#include <exception>
28+
#include "utils.h"
29+
30+
const size_t NIL = -1;
31+
32+
class ProtovEB {
33+
public:
34+
ProtovEB(size_t kk): k(kk), u(1 << (1 << k)), sqrt_bit(1 << (k - 1)),
35+
sqrtu(1 << sqrt_bit) {
36+
if (k) {
37+
summary = new ProtovEB(k - 1);
38+
cluster = new ProtovEB* [sqrtu];
39+
for (size_t i = 0; i < sqrtu; i++)
40+
cluster[i] = new ProtovEB(k - 1);
41+
} else {
42+
A(0) = 0;
43+
A(1) = 0;
44+
}
45+
}
46+
bool& A(size_t i) {
47+
switch (i) {
48+
case 0:
49+
return reinterpret_cast<bool*>(&summary)[0];
50+
case 1:
51+
return reinterpret_cast<bool*>(&cluster)[0];
52+
default:
53+
throw std::invalid_argument("array out of range");
54+
}
55+
}
56+
// indexing
57+
size_t high(size_t x) { return x >> sqrt_bit; }
58+
size_t low(size_t x) { return x & (sqrtu - 1); }
59+
size_t index(size_t x, size_t y) { return x << sqrt_bit | y; }
60+
// algorithms
61+
bool ProtovEBMember(size_t x) {
62+
if (k)
63+
return cluster[high(x)]->ProtovEBMember(low(x));
64+
else
65+
return A(x);
66+
}
67+
size_t ProtovEBMinimum() {
68+
if (k) {
69+
size_t min_c = summary->ProtovEBMinimum();
70+
if (min_c == NIL)
71+
return NIL;
72+
else
73+
return index(min_c, cluster[min_c]->ProtovEBMinimum());
74+
} else {
75+
if (A(0))
76+
return 0;
77+
else if (A(1))
78+
return 1;
79+
else
80+
return NIL;
81+
}
82+
}
83+
size_t ProtovEBMaximum() {
84+
if (k) {
85+
size_t min_c = summary->ProtovEBMaximum();
86+
if (min_c == NIL)
87+
return NIL;
88+
else
89+
return index(min_c, cluster[min_c]->ProtovEBMaximum());
90+
} else {
91+
if (A(1))
92+
return 1;
93+
else if (A(0))
94+
return 0;
95+
else
96+
return NIL;
97+
}
98+
}
99+
size_t ProtovEBSuccessor(size_t x) {
100+
if (k) {
101+
size_t offset = cluster[high(x)]->ProtovEBSuccessor(low(x));
102+
if (offset != NIL)
103+
return index(high(x), offset);
104+
else {
105+
size_t succ_c = summary->ProtovEBSuccessor(high(x));
106+
if (succ_c == NIL)
107+
return NIL;
108+
else {
109+
size_t offset = cluster[succ_c]->ProtovEBMinimum();
110+
return index(succ_c, offset);
111+
}
112+
}
113+
} else {
114+
if (x == 0 && A(1))
115+
return 1;
116+
else
117+
return NIL;
118+
}
119+
}
120+
size_t ProtovEBPredecessor(size_t x) {
121+
if (k) {
122+
size_t offset = cluster[high(x)]->ProtovEBPredecessor(low(x));
123+
if (offset != NIL)
124+
return index(high(x), offset);
125+
else {
126+
size_t succ_c = summary->ProtovEBPredecessor(high(x));
127+
if (succ_c == NIL)
128+
return NIL;
129+
else {
130+
size_t offset = cluster[succ_c]->ProtovEBMaximum();
131+
return index(succ_c, offset);
132+
}
133+
}
134+
} else {
135+
if (x == 1 && A(0))
136+
return 0;
137+
else
138+
return NIL;
139+
}
140+
}
141+
void ProtovEBInsert(size_t x) {
142+
if (k) {
143+
cluster[high(x)]->ProtovEBInsert(low(x));
144+
summary->ProtovEBInsert(high(x));
145+
} else
146+
A(x) = true;
147+
}
148+
bool ProtovEBDelete(size_t x) {
149+
if (k) {
150+
if (!cluster[high(x)]->ProtovEBDelete(low(x)))
151+
if (!summary->ProtovEBDelete(high(x))) {
152+
return summary->ProtovEBMinimum() != NIL;
153+
}
154+
return true;
155+
} else {
156+
A(x) = false;
157+
return A(0) || A(1);
158+
}
159+
}
160+
// members
161+
ProtovEB* summary; // A[0] when u == 2
162+
ProtovEB** cluster; // A[1] when u == 2
163+
~ProtovEB() {
164+
if (k) {
165+
for (size_t i = 0; i < sqrtu; i++)
166+
delete cluster[i];
167+
delete [] cluster;
168+
delete summary;
169+
}
170+
}
171+
size_t k, u, sqrt_bit, sqrtu;
172+
};
173+
#endif
174+
175+
#ifdef MAIN_ProtovEB
176+
void print(size_t x) {
177+
if (x == NIL)
178+
std::cout << "NIL" << std::endl;
179+
else
180+
std::cout << x << std::endl;
181+
}
182+
183+
void print(bool x) {
184+
std::cout << std::boolalpha << x << std::endl;
185+
}
186+
187+
int main(int argc, char *argv[]) {
188+
const size_t k = get_argv(argc, argv, 1, 4);
189+
if (k > 4)
190+
throw std::invalid_argument("k too large");
191+
ProtovEB Pv(k);
192+
std::cout << "m: member" << std::endl;
193+
std::cout << "-: minimum" << std::endl;
194+
std::cout << "+: maximum" << std::endl;
195+
std::cout << "p: predecessor" << std::endl;
196+
std::cout << "s: successor" << std::endl;
197+
std::cout << "i: insert" << std::endl;
198+
std::cout << "d: delete" << std::endl;
199+
std::cout << "P: print all" << std::endl;
200+
std::cout << "q: quit" << std::endl;
201+
while (true) {
202+
char c; size_t x; std::vector<size_t> l;
203+
std::cout << ">> ";
204+
if (!(std::cin >> c)) {
205+
std::cout << std::endl;
206+
break;
207+
}
208+
switch (c) {
209+
case 'm':
210+
std::cout << "x = ";
211+
std::cin >> x;
212+
print(Pv.ProtovEBMember(x));
213+
break;
214+
case '-':
215+
print(Pv.ProtovEBMinimum());
216+
break;
217+
case '+':
218+
print(Pv.ProtovEBMaximum());
219+
break;
220+
case 'p':
221+
std::cout << "x = ";
222+
std::cin >> x;
223+
print(Pv.ProtovEBPredecessor(x));
224+
break;
225+
case 's':
226+
std::cout << "x = ";
227+
std::cin >> x;
228+
print(Pv.ProtovEBSuccessor(x));
229+
break;
230+
case 'i':
231+
std::cout << "x = ";
232+
std::cin >> x;
233+
Pv.ProtovEBInsert(x);
234+
break;
235+
case 'd':
236+
std::cout << "x = ";
237+
std::cin >> x;
238+
Pv.ProtovEBDelete(x);
239+
break;
240+
case 'P':
241+
for (size_t i = 0; i < Pv.u; i++)
242+
if (Pv.ProtovEBMember(i))
243+
l.push_back(i);
244+
output_integers(l);
245+
break;
246+
case 'q':
247+
return 0;
248+
}
249+
}
250+
return 0;
251+
}
252+
#endif
253+

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,8 @@
125125
| 19 | FibHeap.cpp | Cut | 519 |
126126
| 19 | FibHeap.cpp | Cascading Cut | 519 |
127127
| 19 | FibHeap.cpp | Fib Heap Delete | 522 |
128+
| 20 | ProtovEB.cpp | Proto vEB Member | 541 |
129+
| 20 | ProtovEB.cpp | Proto vEB Minimum | 542 |
130+
| 20 | ProtovEB.cpp | Proto vEB Successor | 543 |
131+
| 20 | ProtovEB.cpp | Proto vEB Insert | 544 |
132+
| 20 | ProtovEB.cpp | Proto vEB Delete | 544 |

0 commit comments

Comments
 (0)