Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_segment_tree_test.cc
Go to the documentation of this file.
1/*
2 Aleph_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
31
37# include <gtest/gtest.h>
38
39# include <tpl_segment_tree.H>
40
41# include <algorithm>
42# include <cstddef>
43# include <numeric>
44# include <random>
45# include <utility>
46# include <vector>
47
48using namespace Aleph;
49using namespace testing;
50
51namespace
52{
53 // Brute-force helpers
54 template <typename T>
55 T brute_sum(const std::vector<T> & v, size_t l, size_t r)
56 {
57 T s = T();
58 for (size_t i = l; i <= r; ++i)
59 s += v[i];
60 return s;
61 }
62
63 template <typename T>
64 T brute_min(const std::vector<T> & v, size_t l, size_t r)
65 {
66 return *std::min_element(v.begin() + l, v.begin() + r + 1);
67 }
68
69 template <typename T>
70 T brute_max(const std::vector<T> & v, size_t l, size_t r)
71 {
72 return *std::max_element(v.begin() + l, v.begin() + r + 1);
73 }
74
75 // XOR operation for custom monoid test
76 struct Xor_Op
77 {
78 constexpr int operator()(const int a, const int b) const noexcept
79 {
80 return a ^ b;
81 }
82 };
83
84 // GCD operation
85 struct Gcd_Op
86 {
87 int operator()(const int a, const int b) const noexcept
88 {
89 return std::gcd(a, b);
90 }
91 };
92} // namespace
93
94// =================================================================
95// Gen_Segment_Tree tests
96// =================================================================
97
99{
101
102 EXPECT_TRUE(st.is_empty());
103 EXPECT_EQ(st.size(), 0U);
104 EXPECT_THROW(st.get(0), std::out_of_range);
105 EXPECT_THROW(st.query(0, 0), std::out_of_range);
106}
107
109{
111
112 EXPECT_EQ(st.size(), 8U);
114
115 for (size_t i = 0; i < 8; ++i)
116 EXPECT_EQ(st.get(i), 5);
117
118 EXPECT_EQ(st.query(0, 7), 40);
119 EXPECT_EQ(st.query(2, 5), 20);
120}
121
123{
124 const std::vector<int> values = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
126
127 for (size_t l = 0; l < values.size(); ++l)
128 for (size_t r = l; r < values.size(); ++r)
129 EXPECT_EQ(st.query(l, r), brute_sum(values, l, r));
130}
131
133{
134 const std::vector<int> values = {9, 4, 7, 1, 8, 2, 6, 3, 5, 0};
135 Min_Segment_Tree<int> st(values);
136
137 for (size_t l = 0; l < values.size(); ++l)
138 for (size_t r = l; r < values.size(); ++r)
139 EXPECT_EQ(st.query(l, r), brute_min(values, l, r));
140}
141
143{
144 const std::vector<int> values = {9, 4, 7, 1, 8, 2, 6, 3, 5, 0};
145 Max_Segment_Tree<int> st(values);
146
147 for (size_t l = 0; l < values.size(); ++l)
148 for (size_t r = l; r < values.size(); ++r)
149 EXPECT_EQ(st.query(l, r), brute_max(values, l, r));
150}
151
153{
154 Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
155
156 st.update(2, 10); // a[2] += 10 => {1, 2, 13, 4, 5}
157 EXPECT_EQ(st.get(2), 13);
158 EXPECT_EQ(st.query(0, 4), 25);
159 EXPECT_EQ(st.query(1, 3), 19);
160}
161
163{
164 Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
165
166 st.set(2, 100);
167 EXPECT_EQ(st.get(2), 100);
168 EXPECT_EQ(st.query(0, 4), 112);
169
170 st.set(0, 0);
171 EXPECT_EQ(st.get(0), 0);
172 EXPECT_EQ(st.query(0, 4), 111);
173}
174
176{
177 const std::vector<int> values = {5, 3, 7, 1, 9, 2, 8, 4, 6};
178
180
181 Array<int> arr;
182 for (const int x : values)
183 arr.append(x);
185
186 DynList<int> list;
187 for (const int x : values)
188 list.append(x);
190
191 Sum_Segment_Tree<int> from_init = {5, 3, 7, 1, 9, 2, 8, 4, 6};
192
193 for (size_t l = 0; l < values.size(); ++l)
194 for (size_t r = l; r < values.size(); ++r)
195 {
196 const int expected = brute_sum(values, l, r);
197 EXPECT_EQ(from_vector.query(l, r), expected);
198 EXPECT_EQ(from_array.query(l, r), expected);
199 EXPECT_EQ(from_list.query(l, r), expected);
200 EXPECT_EQ(from_init.query(l, r), expected);
201 }
202}
203
205{
206 const std::vector<int> values = {3, 5, 7, 2, 8};
207 Gen_Segment_Tree<int, Xor_Op> st(values, 0, Xor_Op{});
208
209 // XOR of full range
210 int expected = 0;
211 for (int v : values)
212 expected ^= v;
213 EXPECT_EQ(st.query(0, 4), expected);
214
215 // Single element
216 EXPECT_EQ(st.query(2, 2), 7);
217
218 // Subrange [1, 3] = 5 ^ 7 ^ 2 = 0
219 EXPECT_EQ(st.query(1, 3), 5 ^ 7 ^ 2);
220}
221
223{
224 const std::vector<int> values = {12, 18, 24, 36, 60};
225 Gen_Segment_Tree<int, Gcd_Op> st(values, 0, Gcd_Op{});
226
227 EXPECT_EQ(st.query(0, 1), std::gcd(12, 18)); // 6
228 EXPECT_EQ(st.query(0, 4), 6);
229 EXPECT_EQ(st.query(2, 4), std::gcd(std::gcd(24, 36), 60)); // 12
230}
231
233{
234 Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
235
236 // Copy
238 EXPECT_EQ(copy.query(0, 4), 15);
239
240 // Move
241 Sum_Segment_Tree<int> moved = std::move(copy);
242 EXPECT_EQ(moved.query(0, 4), 15);
243
244 // Swap
245 Sum_Segment_Tree<int> other = {10, 20, 30};
247
248 EXPECT_EQ(moved.size(), 3U);
249 EXPECT_EQ(moved.query(0, 2), 60);
250 EXPECT_EQ(other.size(), 5U);
251 EXPECT_EQ(other.query(0, 4), 15);
252}
253
255{
256 Sum_Segment_Tree<int> st = {1, 2, 3};
257
258 EXPECT_THROW(st.get(3), std::out_of_range);
259 EXPECT_THROW(st.query(0, 3), std::out_of_range);
260 EXPECT_THROW(st.query(2, 1), std::out_of_range);
261 EXPECT_THROW(st.update(3, 1), std::out_of_range);
262 EXPECT_THROW(st.set(3, 1), std::out_of_range);
263}
264
266{
267 Sum_Segment_Tree<int> st = {42};
268
269 EXPECT_EQ(st.size(), 1U);
270 EXPECT_EQ(st.get(0), 42);
271 EXPECT_EQ(st.query(0, 0), 42);
272
273 st.update(0, 8);
274 EXPECT_EQ(st.get(0), 50);
275
276 st.set(0, 100);
277 EXPECT_EQ(st.get(0), 100);
278}
279
281{
282 Min_Segment_Tree<int> st = {5, 3};
283
284 EXPECT_EQ(st.query(0, 1), 3);
285 EXPECT_EQ(st.query(0, 0), 5);
286 EXPECT_EQ(st.query(1, 1), 3);
287
288 st.set(1, 10);
289 EXPECT_EQ(st.query(0, 1), 5);
290}
291
293{
294 Sum_Segment_Tree<int> st = {3, 1, 4, 1, 5};
295 auto vals = st.values();
296
297 ASSERT_EQ(vals.size(), 5U);
298 EXPECT_EQ(vals(0), 3);
299 EXPECT_EQ(vals(1), 1);
300 EXPECT_EQ(vals(2), 4);
301 EXPECT_EQ(vals(3), 1);
302 EXPECT_EQ(vals(4), 5);
303}
304
306{
307 constexpr size_t N = 1000;
308 constexpr size_t OPS = 5000;
309
310 std::mt19937 rng(42);
311 std::uniform_int_distribution<int> val_dist(-100, 100);
312 std::uniform_int_distribution<size_t> idx_dist(0, N - 1);
313
314 std::vector<int> brute(N);
315 for (size_t i = 0; i < N; ++i)
316 brute[i] = val_dist(rng);
317
319
320 for (size_t op = 0; op < OPS; ++op)
321 {
322 if (rng() % 2 == 0)
323 {
324 // update
325 size_t i = idx_dist(rng);
326 int delta = val_dist(rng);
327 brute[i] += delta;
328 st.update(i, delta);
329 }
330 else
331 {
332 // query
333 size_t a = idx_dist(rng);
334 size_t b = idx_dist(rng);
335 if (a > b) std::swap(a, b);
336 EXPECT_EQ(st.query(a, b), brute_sum(brute, a, b));
337 }
338 }
339}
340
342{
343 constexpr size_t N = 500;
344 constexpr size_t OPS = 3000;
345
346 std::mt19937 rng(123);
347 std::uniform_int_distribution<int> val_dist(-1000, 1000);
348 std::uniform_int_distribution<size_t> idx_dist(0, N - 1);
349
350 std::vector<int> brute(N);
351 for (size_t i = 0; i < N; ++i)
352 brute[i] = val_dist(rng);
353
355
356 for (size_t op = 0; op < OPS; ++op)
357 {
358 if (rng() % 2 == 0)
359 {
360 // set
361 size_t i = idx_dist(rng);
362 int val = val_dist(rng);
363 brute[i] = val;
364 st.set(i, val);
365 }
366 else
367 {
368 // query
369 size_t a = idx_dist(rng);
370 size_t b = idx_dist(rng);
371 if (a > b) std::swap(a, b);
372 EXPECT_EQ(st.query(a, b), brute_min(brute, a, b));
373 }
374 }
375}
376
377// =================================================================
378// Typedef convenience tests
379// =================================================================
380
382{
383 Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
384 EXPECT_EQ(st.query(0, 4), 15);
385 st.update(2, 7);
386 EXPECT_EQ(st.query(0, 4), 22);
387}
388
390{
391 Min_Segment_Tree<int> st = {5, 2, 4, 7, 1, 3};
392 EXPECT_EQ(st.query(0, 5), 1);
393 EXPECT_EQ(st.query(0, 3), 2);
394 st.set(4, 10);
395 EXPECT_EQ(st.query(0, 5), 2);
396}
397
399{
400 Max_Segment_Tree<int> st = {5, 2, 4, 7, 1, 3};
401 EXPECT_EQ(st.query(0, 5), 7);
402 EXPECT_EQ(st.query(4, 5), 3);
403 st.set(3, 0);
404 EXPECT_EQ(st.query(0, 5), 5);
405}
406
408{
409 Sum_Segment_Tree<double> st = {1.5, 2.5, 3.0};
410 EXPECT_DOUBLE_EQ(st.query(0, 2), 7.0);
411 st.update(1, 0.5);
412 EXPECT_DOUBLE_EQ(st.query(0, 2), 7.5);
413}
414
415// =================================================================
416// Gen_Lazy_Segment_Tree tests
417// =================================================================
418
420{
422
423 EXPECT_TRUE(st.is_empty());
424 EXPECT_EQ(st.size(), 0U);
425 EXPECT_THROW(st.query(0, 0), std::out_of_range);
426}
427
429{
430 Lazy_Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
431
432 st.update(1, 3, 10); // a[1..3] += 10
433 EXPECT_EQ(st.query(0, 4), 45);
434 EXPECT_EQ(st.get(0), 1);
435 EXPECT_EQ(st.get(1), 12);
436 EXPECT_EQ(st.get(2), 13);
437 EXPECT_EQ(st.get(3), 14);
438 EXPECT_EQ(st.get(4), 5);
439}
440
442{
444
445 st.update(0, 4, 5); // [0..4] += 5
446 st.update(3, 7, 3); // [3..7] += 3
447 st.update(6, 9, 1); // [6..9] += 1
448
449 // Expected: {5, 5, 5, 8, 8, 3, 4, 4, 1, 1}
450 EXPECT_EQ(st.get(0), 5);
451 EXPECT_EQ(st.get(3), 8);
452 EXPECT_EQ(st.get(5), 3);
453 EXPECT_EQ(st.get(6), 4);
454 EXPECT_EQ(st.get(9), 1);
455 EXPECT_EQ(st.query(0, 9), 44);
456}
457
459{
460 Lazy_Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
461
462 st.point_update(2, 100);
463 EXPECT_EQ(st.get(2), 103);
464 EXPECT_EQ(st.query(0, 4), 115);
465}
466
468{
469 Lazy_Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
470
471 st.set(2, 100);
472 EXPECT_EQ(st.get(2), 100);
473 EXPECT_EQ(st.query(0, 4), 112);
474}
475
477{
478 const std::vector<int> values = {5, 3, 7, 1, 9};
479
481
482 Array<int> arr;
483 for (const int x : values)
484 arr.append(x);
486
487 DynList<int> list;
488 for (const int x : values)
489 list.append(x);
491
492 Lazy_Sum_Segment_Tree<int> from_init = {5, 3, 7, 1, 9};
493
494 for (size_t l = 0; l < values.size(); ++l)
495 for (size_t r = l; r < values.size(); ++r)
496 {
497 const int expected = brute_sum(values, l, r);
498 EXPECT_EQ(from_vector.query(l, r), expected);
499 EXPECT_EQ(from_array.query(l, r), expected);
500 EXPECT_EQ(from_list.query(l, r), expected);
501 EXPECT_EQ(from_init.query(l, r), expected);
502 }
503}
504
506{
507 Lazy_Sum_Segment_Tree<int> st = {1, 2, 3, 4, 5};
508
510 EXPECT_EQ(copy.query(0, 4), 15);
511
513 EXPECT_EQ(moved.query(0, 4), 15);
514
515 Lazy_Sum_Segment_Tree<int> other = {10, 20, 30};
517
518 EXPECT_EQ(moved.size(), 3U);
519 EXPECT_EQ(moved.query(0, 2), 60);
520 EXPECT_EQ(other.size(), 5U);
521 EXPECT_EQ(other.query(0, 4), 15);
522}
523
525{
526 Lazy_Sum_Segment_Tree<int> st = {1, 2, 3};
527
528 EXPECT_THROW(st.query(0, 3), std::out_of_range);
529 EXPECT_THROW(st.query(2, 1), std::out_of_range);
530 EXPECT_THROW(st.update(0, 3, 1), std::out_of_range);
531 EXPECT_THROW(st.set(3, 1), std::out_of_range);
532}
533
535{
537
538 EXPECT_EQ(st.get(0), 42);
539 st.update(0, 0, 8);
540 EXPECT_EQ(st.get(0), 50);
541 st.set(0, 100);
542 EXPECT_EQ(st.get(0), 100);
543}
544
546{
547 constexpr size_t N = 200;
548 constexpr size_t OPS = 2000;
549
550 std::mt19937 rng(99);
551 std::uniform_int_distribution<int> val_dist(-50, 50);
552 std::uniform_int_distribution<size_t> idx_dist(0, N - 1);
553
554 std::vector<int> brute(N, 0);
556
557 for (size_t op = 0; op < OPS; ++op)
558 {
559 size_t a = idx_dist(rng);
560 size_t b = idx_dist(rng);
561 if (a > b) std::swap(a, b);
562
563 if (rng() % 2 == 0)
564 {
565 int delta = val_dist(rng);
566 for (size_t i = a; i <= b; ++i)
567 brute[i] += delta;
568 st.update(a, b, delta);
569 }
570 else
571 {
572 EXPECT_EQ(st.query(a, b), brute_sum(brute, a, b));
573 }
574 }
575}
576
577// =================================================================
578// Policy-specific tests
579// =================================================================
580
582{
583 Lazy_Min_Segment_Tree<int> st = {5, 3, 7, 1, 9};
584
585 EXPECT_EQ(st.query(0, 4), 1);
586 st.update(2, 4, -5); // {5, 3, 2, -4, 4}
587 EXPECT_EQ(st.query(0, 4), -4);
588 EXPECT_EQ(st.query(0, 1), 3);
589}
590
592{
593 Lazy_Max_Segment_Tree<int> st = {5, 3, 7, 1, 9};
594
595 EXPECT_EQ(st.query(0, 4), 9);
596 st.update(0, 3, 10); // {15, 13, 17, 11, 9}
597 EXPECT_EQ(st.query(0, 4), 17);
598 EXPECT_EQ(st.query(3, 4), 11);
599}
600
602{
604
605 // Range assign: set [1..3] to 10
606 st.update(1, 3, {true, 10});
607 EXPECT_EQ(st.get(0), 1);
608 EXPECT_EQ(st.get(1), 10);
609 EXPECT_EQ(st.get(2), 10);
610 EXPECT_EQ(st.get(3), 10);
611 EXPECT_EQ(st.get(4), 5);
612 EXPECT_EQ(st.query(0, 4), 36);
613
614 // Overlapping assign
615 st.update(2, 4, {true, 0});
616 EXPECT_EQ(st.query(0, 4), 11); // {1, 10, 0, 0, 0}
617}
618
620{
621 constexpr size_t N = 100;
622 constexpr size_t OPS = 1000;
623
624 std::mt19937 rng(77);
625 std::uniform_int_distribution<int> val_dist(-20, 20);
626 std::uniform_int_distribution<size_t> idx_dist(0, N - 1);
627
628 std::vector<int> brute(N, 0);
630
631 for (size_t op = 0; op < OPS; ++op)
632 {
633 size_t a = idx_dist(rng);
634 size_t b = idx_dist(rng);
635 if (a > b) std::swap(a, b);
636
637 if (rng() % 2 == 0)
638 {
639 int delta = val_dist(rng);
640 for (size_t i = a; i <= b; ++i)
641 brute[i] += delta;
642 st.update(a, b, delta);
643 }
644 else
645 {
646 EXPECT_EQ(st.query(a, b), brute_min(brute, a, b));
647 }
648 }
649}
650
651// =================================================================
652// Segment_Tree_Beats tests
653// =================================================================
654
656{
658
659 EXPECT_TRUE(st.is_empty());
660 EXPECT_EQ(st.size(), 0U);
661 EXPECT_THROW(st.query_sum(0, 0), std::out_of_range);
662}
663
665{
666 Segment_Tree_Beats<int> st = {5, 2, 4, 7, 1, 3};
667
668 st.chmin(0, 5, 4);
669 // {4, 2, 4, 4, 1, 3}
670 EXPECT_EQ(st.query_max(0, 5), 4);
671 EXPECT_EQ(st.query_min(0, 5), 1);
672 EXPECT_EQ(st.query_sum(0, 5), 18);
673}
674
676{
677 Segment_Tree_Beats<int> st = {5, 2, 4, 7, 1, 3};
678
679 st.chmax(0, 5, 4);
680 // {5, 4, 4, 7, 4, 4}
681 EXPECT_EQ(st.query_min(0, 5), 4);
682 EXPECT_EQ(st.query_max(0, 5), 7);
683 EXPECT_EQ(st.query_sum(0, 5), 28);
684}
685
687{
688 Segment_Tree_Beats<int> st = {10, 20, 30, 40, 50};
689
690 st.chmin(0, 4, 35); // {10, 20, 30, 35, 35}
691 st.chmax(0, 4, 25); // {25, 25, 30, 35, 35}
692
693 EXPECT_EQ(st.query_sum(0, 4), 150);
694 EXPECT_EQ(st.query_min(0, 4), 25);
695 EXPECT_EQ(st.query_max(0, 4), 35);
696}
697
699{
700 Segment_Tree_Beats<int> st = {1, 2, 3, 4, 5, 6, 7, 8};
701
702 st.chmin(2, 5, 4); // {1, 2, 3, 4, 4, 4, 7, 8}
703 EXPECT_EQ(st.query_sum(0, 7), 33);
704
705 st.chmax(0, 3, 3); // {3, 3, 3, 4, 4, 4, 7, 8}
706 EXPECT_EQ(st.query_sum(0, 7), 36);
707}
708
710{
711 Segment_Tree_Beats<int> st = {42};
712
713 EXPECT_EQ(st.query_sum(0, 0), 42);
714 EXPECT_EQ(st.query_min(0, 0), 42);
715 EXPECT_EQ(st.query_max(0, 0), 42);
716
717 st.chmin(0, 0, 10);
718 EXPECT_EQ(st.get(0), 10);
719
720 st.chmax(0, 0, 20);
721 EXPECT_EQ(st.get(0), 20);
722}
723
725{
726 Segment_Tree_Beats<int> st = {1, 2, 3, 4, 5};
727
729 EXPECT_EQ(copy.query_sum(0, 4), 15);
730
732 EXPECT_EQ(moved.query_sum(0, 4), 15);
733
736
737 EXPECT_EQ(moved.size(), 2U);
738 EXPECT_EQ(moved.query_sum(0, 1), 30);
739 EXPECT_EQ(other.size(), 5U);
740 EXPECT_EQ(other.query_sum(0, 4), 15);
741}
742
744{
745 Segment_Tree_Beats<int> st = {1, 2, 3};
746
747 EXPECT_THROW(st.query_sum(0, 3), std::out_of_range);
748 EXPECT_THROW(st.chmin(0, 3, 0), std::out_of_range);
749 EXPECT_THROW(st.chmax(2, 1, 0), std::out_of_range);
750}
751
753{
754 constexpr size_t N = 100;
755 constexpr size_t OPS = 1000;
756
757 std::mt19937 rng(2024);
758 std::uniform_int_distribution<int> val_dist(0, 100);
759 std::uniform_int_distribution<size_t> idx_dist(0, N - 1);
760 std::uniform_int_distribution<int> op_dist(0, 4);
761
762 std::vector<int> brute(N);
763 for (size_t i = 0; i < N; ++i)
764 brute[i] = val_dist(rng);
765
767
768 for (size_t op = 0; op < OPS; ++op)
769 {
770 size_t a = idx_dist(rng);
771 size_t b = idx_dist(rng);
772 if (a > b) std::swap(a, b);
773
774 switch (op_dist(rng))
775 {
776 case 0:
777 {
778 // chmin
779 int v = val_dist(rng);
780 for (size_t i = a; i <= b; ++i)
781 brute[i] = std::min(brute[i], v);
782 st.chmin(a, b, v);
783 break;
784 }
785 case 1:
786 {
787 // chmax
788 int v = val_dist(rng);
789 for (size_t i = a; i <= b; ++i)
790 brute[i] = std::max(brute[i], v);
791 st.chmax(a, b, v);
792 break;
793 }
794 case 2:
795 EXPECT_EQ(st.query_sum(a, b), brute_sum(brute, a, b));
796 break;
797 case 3:
798 EXPECT_EQ(st.query_max(a, b), brute_max(brute, a, b));
799 break;
800 case 4:
801 EXPECT_EQ(st.query_min(a, b), brute_min(brute, a, b));
802 break;
803 }
804 }
805
806 // Final full verification
807 for (size_t i = 0; i < N; ++i)
808 EXPECT_EQ(st.get(i), brute[i]);
809}
810
812{
813 Segment_Tree_Beats<int> st = {10, 20, 30, 40, 50};
814 st.chmin(0, 4, 35);
815
816 auto vals = st.values();
817 ASSERT_EQ(vals.size(), 5U);
818 EXPECT_EQ(vals(0), 10);
819 EXPECT_EQ(vals(1), 20);
820 EXPECT_EQ(vals(2), 30);
821 EXPECT_EQ(vals(3), 35);
822 EXPECT_EQ(vals(4), 35);
823}
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:245
Dynamic singly linked list with functional programming support.
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
Lazy segment tree with range update and range query.
void point_update(const size_t i, const lazy_type &delta)
Point update: apply delta to a[i].
constexpr size_t size() const noexcept
Number of logical elements.
value_type query(const size_t l, const size_t r) const
Range query over [l, r].
constexpr bool is_empty() const noexcept
True if the tree contains no elements.
void update(const size_t l, const size_t r, const lazy_type &val)
Range update: apply val to every a[i] with l <= i <= r.
void set(const size_t i, const value_type &val)
Set a[i] = val.
void swap(Gen_Lazy_Segment_Tree &other) noexcept(noexcept(std::swap(std::declval< Policy & >(), std::declval< Policy & >())))
Swap this tree with other in O(1).
value_type get(const size_t i) const
Retrieve the value a[i].
Segment tree over an arbitrary associative binary operation.
void set(const size_t i, const T &val)
Set a[i] = val.
void swap(Gen_Segment_Tree &other) noexcept(noexcept(std::swap(std::declval< T & >(), std::declval< T & >())) and noexcept(std::swap(std::declval< Op & >(), std::declval< Op & >())))
Swap this tree with other in O(1).
T query(const size_t l, const size_t r) const
Range query over [l, r].
constexpr bool is_empty() const noexcept
True if the tree contains no elements.
Array< T > values() const
Reconstruct all original values into an Array.
T get(const size_t i) const
Retrieve the value a[i].
void update(const size_t i, const T &delta)
Point update: a[i] = Op(a[i], delta).
constexpr size_t size() const noexcept
Number of logical elements.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1065
Ji Driver's Segment Tree (Segment Tree Beats).
void chmax(const size_t l, const size_t r, const T &v)
Range chmax: for each i in [l, r], set a[i] = max(a[i], v).
constexpr size_t size() const noexcept
Number of logical elements.
T query_sum(const size_t l, const size_t r) const
Range sum query over [l, r].
T get(const size_t i) const
Retrieve the value at position i.
T query_max(const size_t l, const size_t r) const
Range max query over [l, r].
void chmin(const size_t l, const size_t r, const T &v)
Range chmin: for each i in [l, r], set a[i] = min(a[i], v).
Array< T > values() const
Reconstruct all values into an Array.
T query_min(const size_t l, const size_t r) const
Range min query over [l, r].
void swap(Segment_Tree_Beats &other) noexcept
Swap this tree with other in O(1).
constexpr bool is_empty() const noexcept
True if the tree contains no elements.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
#define TEST(name)
T brute_sum(const vector< T > &v, size_t l, size_t r)
static mt19937 rng
T brute_min(const vector< T > &v, size_t l, size_t r)
#define N
Definition fib.C:294
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
Definition ahAlgo.H:584
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.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
T brute_max(const vector< T > &v, size_t l, size_t r)
Lazy segment tree for range add + range max.
Lazy segment tree for range add + range min.
Lazy segment tree for range add + range sum.
Max Segment Tree for range maximum queries with point updates.
Min Segment Tree for range minimum queries with point updates.
Sum Segment Tree for range sum queries with point updates.
int operator()(const int &a, const int &b) const noexcept
constexpr unsigned operator()(unsigned a, unsigned b) const noexcept
gsl_rng * r
Segment trees for dynamic range queries with lazy propagation.
DynList< int > l