76 "========================================================\n"
77 " SCENARIO 1: El Arbol Genealogico de los Datos\n"
78 "========================================================\n\n";
83 std::cout <<
"Array of ages: {45, 23, 67, 12, 56, 34, 78}\n\n";
85 std::cout <<
"Cartesian Tree structure (min-heap):\n";
86 std::cout <<
" Root: index " <<
ct.
root()
87 <<
" (age " <<
ct.data_at(
ct.root()) <<
")\n\n";
89 std::cout << std::setw(8) <<
"Index" << std::setw(8) <<
"Age"
90 << std::setw(10) <<
"Parent" << std::setw(10) <<
"Left"
91 << std::setw(10) <<
"Right" << std::setw(8) <<
"Leaf?"
93 std::cout << std::string(54,
'-') <<
"\n";
95 for (
size_t i = 0; i <
ct.size(); ++i)
97 auto fmt = [](
size_t v) -> std::string {
100 std::cout << std::setw(8) << i
101 << std::setw(8) <<
ct.data_at(i)
102 << std::setw(10) <<
fmt(
ct.parent_of(i))
103 << std::setw(10) <<
fmt(
ct.left_child(i))
104 << std::setw(10) <<
fmt(
ct.right_child(i))
105 << std::setw(8) << (
ct.is_leaf(i) ?
"yes" :
"no")
109 std::cout <<
"\nTree height: " <<
ct.height() <<
"\n";
112 auto io =
ct.inorder();
113 std::cout <<
"\nInorder traversal: {";
114 for (
size_t i = 0; i <
io.size(); ++i)
115 std::cout << (i ?
", " :
"") <<
io(i);
119 for (
size_t i = 0; i <
io.size(); ++i)
121 std::cout <<
"Inorder = {0, 1, ..., n-1}? "
133 "========================================================\n"
134 " SCENARIO 2: Ancestros Comunes en el Linaje\n"
135 "========================================================\n\n";
139 std::cout <<
"Array: {45, 23, 67, 12, 56, 34, 78}\n\n";
143 std::cout <<
"Euler Tour (" << lca.
euler_tour_size() <<
" entries):\n ";
144 for (
size_t i = 0; i < euler.size(); ++i)
145 std::cout << (i ?
", " :
"") << euler(i);
149 std::cout <<
"Node depths:\n";
150 for (
size_t i = 0; i < lca.
size(); ++i)
151 std::cout <<
" Node " << i <<
" (value "
156 std::cout <<
"\nLCA queries:\n";
157 auto show_lca = [&](
size_t u,
size_t v) {
158 size_t a = lca.
lca(u, v);
159 std::cout <<
" LCA(" << u <<
", " << v <<
") = " << a
161 <<
" distance = " << lca.
distance(u, v) <<
"\n";
179 "========================================================\n"
180 " SCENARIO 3: RMQ sin Trucos: de Arbol a Respuestas O(1)\n"
181 "========================================================\n\n";
183 std::vector<int> data = {5, 2, 4, 7, 1, 3, 6, 8, 0, 9};
184 std::cout <<
"Array: {5, 2, 4, 7, 1, 3, 6, 8, 0, 9}\n\n";
190 std::cout <<
"Comparing Cartesian Tree RMQ vs Sparse Table:\n\n";
191 std::cout << std::setw(12) <<
"Range"
192 << std::setw(12) <<
"CT-RMQ"
193 << std::setw(12) <<
"Sparse"
194 << std::setw(10) <<
"Match?"
196 std::cout << std::string(46,
'-') <<
"\n";
201 std::string
range =
"[" + std::to_string(
l) +
"," + std::to_string(
r) +
"]";
202 std::cout << std::setw(12) <<
range
203 << std::setw(12) <<
ct_val
204 << std::setw(12) <<
sp_val
216 std::cout <<
"\nquery_idx(2, 6) = " <<
ct_rmq.query_idx(2, 6)
217 <<
" (value " <<
ct_rmq.get(
ct_rmq.query_idx(2, 6)) <<
")\n";
228 "========================================================\n"
229 " SCENARIO 4: El Circulo Completo: RMQ <-> LCA\n"
230 "========================================================\n\n";
232 constexpr size_t N = 100000;
233 constexpr size_t Q = 500000;
235 std::mt19937
rng(42);
236 std::uniform_int_distribution<int> dist(-100000, 100000);
238 std::vector<int> data(
N);
239 for (
auto & x : data)
242 std::cout <<
"N = " <<
N <<
" elements, Q = " <<
Q <<
" queries\n\n";
245 auto t0 = std::chrono::high_resolution_clock::now();
247 auto t1 = std::chrono::high_resolution_clock::now();
248 double ct_build_ms = std::chrono::duration<double, std::milli>(
t1 -
t0).count();
251 t0 = std::chrono::high_resolution_clock::now();
253 t1 = std::chrono::high_resolution_clock::now();
254 double sp_build_ms = std::chrono::duration<double, std::milli>(
t1 -
t0).count();
256 std::cout <<
"Build times:\n";
257 std::cout <<
" Cartesian Tree RMQ: " << std::fixed << std::setprecision(2)
259 std::cout <<
" Sparse Table: " <<
sp_build_ms <<
" ms\n\n";
262 std::uniform_int_distribution<size_t>
idx_dist(0,
N - 1);
263 std::vector<std::pair<size_t, size_t>>
queries(
Q);
273 t0 = std::chrono::high_resolution_clock::now();
274 volatile int sink = 0;
277 t1 = std::chrono::high_resolution_clock::now();
278 double ct_query_ms = std::chrono::duration<double, std::milli>(
t1 -
t0).count();
281 t0 = std::chrono::high_resolution_clock::now();
284 t1 = std::chrono::high_resolution_clock::now();
285 double sp_query_ms = std::chrono::duration<double, std::milli>(
t1 -
t0).count();
287 std::cout <<
"Query times (" <<
Q <<
" queries):\n";
288 std::cout <<
" Cartesian Tree RMQ: " <<
ct_query_ms <<
" ms\n";
289 std::cout <<
" Sparse Table: " <<
sp_query_ms <<
" ms\n\n";
292 std::cout <<
"Verifying RMQ(l,r) = data[LCA(l,r)] for first 10000 queries... ";
294 const auto & lca_engine =
ct_rmq.lca_engine();
308 std::cout << (
all_ok ?
"ALL MATCH" :
"MISMATCH FOUND") <<
"\n\n";
310 std::cout <<
"The circle is complete:\n"
311 <<
" Array -> Cartesian Tree -> Euler Tour -> "
312 "Sparse Table -> O(1) LCA -> O(1) RMQ\n"
313 <<
" Confirming: RMQ and LCA are equivalent problems.\n";
326 std::cout <<
"\nAll scenarios completed successfully.\n";
constexpr size_t root() const noexcept
Index of the root node.
const T & data_at(const size_t i) const
Value at node i.
size_t euler_tour_size() const noexcept
Size of the Euler Tour (should be 2n-1 for n > 0).
constexpr size_t size() const noexcept
Number of nodes.
const Gen_Cartesian_Tree< T, Comp > & tree() const noexcept
Const reference to the internal Cartesian Tree.
size_t depth_of(const size_t u) const
Depth of node u in the Cartesian Tree.
size_t lca(const size_t u, const size_t v) const
Lowest Common Ancestor of nodes u and v in O(1).
size_t distance(const size_t u, const size_t v) const
Distance between nodes u and v in the tree.
Array< size_t > euler_tour() const
Copy of the Euler Tour array (for inspection/debugging).
Main namespace for Aleph-w library functions.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
Container< T > range(const T start, const T end, const T step=1)
Generate a range of values [start, end] with a given step.
Range minimum queries via Cartesian Tree.
Cartesian Tree for min-heap (range minimum).
LCA on a min-heap Cartesian Tree.
Sparse Table for range minimum queries.
Cartesian Tree, LCA via Euler Tour, and RMQ via Cartesian Tree.
Sparse Table for static range queries in O(1).