Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
sparse_table_example.cc
Go to the documentation of this file.
1/*
2Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
67# include <cstdio>
68# include <iostream>
69# include <iomanip>
70# include <numeric>
71# include <cassert>
72
73# include <tpl_sparse_table.H>
74
75using namespace std;
76using namespace Aleph;
77
78// =====================================================================
79// SCENARIO 1 — Sensor Monitoring (range minimum)
80// =====================================================================
81//
82// A chemical reactor has 20 temperature sensors sampled once. After
83// shutdown the engineer needs:
84// "What was the minimum temperature in sensors 3..10?"
85// "What was the minimum across the entire bank?"
86//
88{
89 cout << "============================================================\n"
90 << " SCENARIO 1: Sensor Monitoring (Sparse_Table — range min)\n"
91 << "============================================================\n\n";
92
93 // Temperatures in °C from 20 sensors
95 72.3, 71.8, 73.1, 69.5, 70.2, 68.9, 74.0, 71.1,
96 67.5, 70.8, 72.0, 73.5, 66.2, 69.0, 71.4, 75.1,
97 68.3, 70.0, 72.7, 69.8
98 };
99
100 cout << "Sensor readings (°C):\n\n";
101 cout << " Sensor Temperature\n"
102 << " ------ -----------\n";
103
104 for (size_t i = 0; i < temps.size(); ++i)
105 cout << " " << setw(6) << i
106 << " " << setw(8) << fixed << setprecision(1)
107 << temps.get(i) << " °C\n";
108
109 cout << "\nTable info: " << temps.size() << " elements, "
110 << temps.num_levels() << " levels\n";
111
112 // -- Queries --
113 struct Query { size_t l; size_t r; const char *label; };
114 Query queries[] = {
115 { 0, 4, "Sensors 0-4 (left bank)" },
116 { 3, 10, "Sensors 3-10 (center section)" },
117 { 10, 19, "Sensors 10-19 (right bank)" },
118 { 0, 19, "All sensors (full bank)" },
119 { 12, 12, "Sensor 12 alone" },
120 { 5, 8, "Sensors 5-8 (hot zone)" },
121 };
122
123 cout << "\nRange minimum queries:\n\n";
124 cout << " Range Min °C Description\n"
125 << " ---------- ------- ----------------------------\n";
126
127 for (auto & q : queries)
128 {
129 double mn = temps.query(q.l, q.r);
130 cout << " [" << setw(2) << q.l << ", " << setw(2) << q.r << "]"
131 << " " << setw(7) << fixed << setprecision(1) << mn
132 << " " << q.label << "\n";
133 }
134
135 // Verify: brute-force check for one query
136 double brute_min = temps.get(3);
137 for (size_t i = 4; i <= 10; ++i)
139 double st_min = temps.query(3, 10);
141 cout << "\n ✓ Brute-force verification passed for [3, 10]\n";
142}
143
144// =====================================================================
145// SCENARIO 2 — Sports Leaderboard (range maximum)
146// =====================================================================
147//
148// Judges score 15 gymnastic routines. The broadcaster wants to
149// quickly find the highest score in any contiguous block.
150//
152{
153 cout << "\n\n============================================================\n"
154 << " SCENARIO 2: Sports Leaderboard (Max_Sparse_Table — range max)\n"
155 << "============================================================\n\n";
156
158 9.1, 8.7, 9.4, 8.9, 9.6, 9.0, 8.5, 9.8,
159 9.2, 8.8, 9.5, 9.3, 8.6, 9.7, 9.1
160 };
161
162 const char *athletes[] = {
163 "Simone B.", "Kohei U.", "Nadia C.", "Daiki H.",
164 "Gabby D.", "Yul M.", "Marian D.", "Larisa L.",
165 "Nastia L.", "Vitaly S.", "Olga K.", "Li Ning",
166 "Mary Lou", "Sawao K.", "Nellie K."
167 };
168
169 cout << "Routine scores:\n\n";
170 cout << " # Athlete Score\n"
171 << " -- ----------- -----\n";
172
173 for (size_t i = 0; i < scores.size(); ++i)
174 cout << " " << setw(2) << i
175 << " " << setw(11) << left << athletes[i] << right
176 << " " << setw(5) << fixed << setprecision(1)
177 << scores.get(i) << "\n";
178
179 struct Query { size_t l; size_t r; const char *label; };
180 Query queries[] = {
181 { 0, 4, "First group (0-4)" },
182 { 5, 9, "Second group (5-9)" },
183 { 10, 14, "Third group (10-14)" },
184 { 0, 14, "Overall best" },
185 { 3, 7, "Mid-competition (3-7)" },
186 { 7, 7, "Single routine (#7)" },
187 };
188
189 cout << "\nRange maximum queries:\n\n";
190 cout << " Range Max Description\n"
191 << " ---------- ------ ----------------------\n";
192
193 for (auto & q : queries)
194 {
195 double mx = scores.query(q.l, q.r);
196 cout << " [" << setw(2) << q.l << ", " << setw(2) << q.r << "]"
197 << " " << setw(5) << fixed << setprecision(1) << mx
198 << " " << q.label << "\n";
199 }
200
201 // Verify
202 assert(scores.query(0, 14) == 9.8);
203 cout << "\n ✓ Overall best = 9.8 (Larisa L.) — verified\n";
204}
205
206// =====================================================================
207// SCENARIO 3 — Range GCD (custom idempotent operation)
208// =====================================================================
209//
210// Given an array of positive integers, answer range-GCD queries.
211// gcd is idempotent: gcd(a, a) = a.
212//
214{
215 cout << "\n\n============================================================\n"
216 << " SCENARIO 3: Range GCD (Gen_Sparse_Table — custom op)\n"
217 << "============================================================\n\n";
218
219 struct Gcd_Op
220 {
221 int operator()(const int & a, const int & b) const noexcept
222 {
223 return gcd(a, b);
224 }
225 };
226
227 Gen_Sparse_Table<int, Gcd_Op> st = {12, 18, 24, 36, 60, 48, 30, 90, 15, 45};
228
229 cout << "Array: ";
230 for (size_t i = 0; i < st.size(); ++i)
231 cout << (i ? ", " : "") << st.get(i);
232 cout << "\n\n";
233
234 cout << "Table info: " << st.size() << " elements, "
235 << st.num_levels() << " levels\n\n";
236
237 struct Query { size_t l; size_t r; };
238 Query queries[] = {
239 {0, 2}, {0, 9}, {3, 5}, {1, 4}, {6, 9}, {4, 4}, {0, 5}, {7, 9},
240 };
241
242 cout << "Range GCD queries:\n\n";
243 cout << " Range GCD Values\n"
244 << " -------- ---- ------\n";
245
246 for (auto & q : queries)
247 {
248 int g = st.query(q.l, q.r);
249
250 // Show the sub-array
251 cout << " [" << q.l << ", " << q.r << "]"
252 << setw(6 - (q.r > 9 ? 1 : 0) - (q.l > 9 ? 1 : 0)) << ""
253 << setw(4) << g << " {";
254 for (size_t i = q.l; i <= q.r; ++i)
255 cout << (i > q.l ? ", " : "") << st.get(i);
256 cout << "}\n";
257
258 // Brute-force verification
259 int brute = st.get(q.l);
260 for (size_t i = q.l + 1; i <= q.r; ++i)
261 brute = gcd(brute, st.get(i));
262 assert(brute == g);
263 }
264
265 cout << "\n ✓ All GCD queries verified against brute-force\n";
266}
267
268// =====================================================================
269// SCENARIO 4 — Construction from different container types
270// =====================================================================
272{
273 cout << "\n\n============================================================\n"
274 << " SCENARIO 4: Construction from different containers\n"
275 << "============================================================\n\n";
276
277 // From Array<T>
278 Array<int> arr = {5, 3, 7, 1, 9, 2, 8, 4, 6};
280 cout << "From Array<int>: min[0,8] = " << st_arr.query(0, 8) << "\n";
281
282 // From std::vector<T>
283 vector<int> vec = {5, 3, 7, 1, 9, 2, 8, 4, 6};
285 cout << "From vector<int>: min[0,8] = " << st_vec.query(0, 8) << "\n";
286
287 // From DynList<T>
288 DynList<int> dl = {5, 3, 7, 1, 9, 2, 8, 4, 6};
290 cout << "From DynList<int>: min[0,8] = " << st_dl.query(0, 8) << "\n";
291
292 // From initializer_list
293 Sparse_Table<int> st_il = {5, 3, 7, 1, 9, 2, 8, 4, 6};
294 cout << "From init-list: min[0,8] = " << st_il.query(0, 8) << "\n";
295
296 assert(st_arr.query(0, 8) == 1);
297 assert(st_vec.query(0, 8) == 1);
298 assert(st_dl.query(0, 8) == 1);
299 assert(st_il.query(0, 8) == 1);
300
301 // values() reconstruction
302 auto vals = st_arr.values();
303 cout << "\nReconstructed values: ";
304 for (size_t i = 0; i < vals.size(); ++i)
305 cout << (i ? ", " : "") << vals(i);
306 cout << "\n";
307
308 cout << "\n ✓ All construction methods produce identical results\n";
309}
310
311// =====================================================================
312
313int main()
314{
319
320 cout << "\n";
321 return 0;
322}
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
Sparse Table over an arbitrary associative and idempotent binary operation.
T get(const size_t i) const
Retrieve the value a[i] in O(1).
constexpr size_t num_levels() const noexcept
Number of precomputed levels (floor(log2(n)) + 1).
constexpr size_t size() const noexcept
Number of logical elements.
T query(const size_t l, const size_t r) const
Range query over [l, r] in O(1).
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
T brute_min(const vector< T > &v, size_t l, size_t r)
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_min_function > > min(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4111
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
static void scenario_sports_leaderboard()
static void scenario_construction()
static void scenario_range_gcd()
static void scenario_sensor_monitoring()
int main()
Sparse Table for range maximum queries.
Sparse Table for range minimum queries.
int operator()(const int &a, const int &b) const noexcept
Sparse Table for static range queries in O(1).
DynList< int > l