37# include <gtest/gtest.h>
44# include <unordered_map>
45# include <unordered_set>
50using namespace testing;
58 std::unordered_set<T> s;
59 for (
size_t i =
l; i <=
r; ++i)
68 std::unordered_map<T, long long> freq;
69 for (
size_t i =
l; i <=
r; ++i)
72 for (
auto & [val, cnt] : freq)
79 std::pair<size_t, T>
brute_mode(
const std::vector<T> & v,
82 std::unordered_map<T, size_t> freq;
83 for (
size_t i =
l; i <=
r; ++i)
87 for (
auto & [val, f] : freq)
99 using answer_type =
long long;
115 answer_type answer()
const {
return sum; }
128 auto ans =
mo.solve(
Array<std::pair<size_t, size_t>>());
136 auto ans =
mo.solve({{0, 0}});
169 auto a1 =
mo1.solve({{0, 2}});
170 auto a2 =
mo2.solve({{0, 2}});
171 auto a3 =
mo3.solve({{0, 2}});
183 auto a1 =
mo1.solve({{0, 3}});
184 auto a2 =
mo2.solve({{0, 3}});
188 auto mo3 = std::move(
mo2);
189 auto a3 =
mo3.solve({{0, 3}});
207 auto ans =
mo.
solve({{0, 0}, {0, 2}, {1, 4}, {0, 5}, {3, 3}});
218 auto ans =
mo.
solve({{0, 0}, {0, 4}, {2, 3}});
227 auto ans =
mo.
solve({{0, 4}, {1, 3}, {2, 2}});
236 std::mt19937
rng(42);
237 std::vector<int>
vec(
N);
242 for (
size_t i = 0; i <
N; ++i)
247 for (
size_t l = 0;
l <
N; ++
l)
248 for (
size_t r =
l;
r <
N; ++
r)
255 for (
size_t l = 0;
l <
N; ++
l)
256 for (
size_t r =
l;
r <
N; ++
r)
259 <<
"l=" <<
l <<
" r=" <<
r;
266 const size_t N = 1000;
267 const size_t Q = 5000;
268 std::mt19937
rng(42);
270 std::vector<int>
vec(
N);
275 for (
size_t i = 0; i <
N; ++i)
279 for (
size_t i = 0; i <
Q; ++i)
281 size_t a =
rng() %
N, b =
rng() %
N;
282 if (a > b) std::swap(a, b);
283 queries.append(std::make_pair(a, b));
289 for (
size_t i = 0; i <
Q; ++i)
293 <<
"query " << i <<
": l=" <<
l <<
" r=" <<
r;
309 auto ans =
mo.
solve({{0, 0}, {0, 2}, {0, 4}});
318 std::mt19937
rng(123);
319 std::vector<int>
vec(
N);
324 for (
size_t i = 0; i <
N; ++i)
328 for (
size_t l = 0;
l <
N; ++
l)
329 for (
size_t r =
l;
r <
N; ++
r)
336 for (
size_t l = 0;
l <
N; ++
l)
337 for (
size_t r =
l;
r <
N; ++
r)
340 <<
"l=" <<
l <<
" r=" <<
r;
347 const size_t N = 500;
348 const size_t Q = 3000;
349 std::mt19937
rng(99);
351 std::vector<int>
vec(
N);
356 for (
size_t i = 0; i <
N; ++i)
360 for (
size_t i = 0; i <
Q; ++i)
362 size_t a =
rng() %
N, b =
rng() %
N;
363 if (a > b) std::swap(a, b);
364 queries.append(std::make_pair(a, b));
370 for (
size_t i = 0; i <
Q; ++i)
374 <<
"query " << i <<
": l=" <<
l <<
" r=" <<
r;
387 auto ans =
mo.
solve({{0, 5}, {0, 0}, {4, 5}});
403 std::mt19937
rng(77);
404 std::vector<int>
vec(
N);
409 for (
size_t i = 0; i <
N; ++i)
413 for (
size_t l = 0;
l <
N; ++
l)
414 for (
size_t r =
l;
r <
N; ++
r)
421 for (
size_t l = 0;
l <
N; ++
l)
422 for (
size_t r =
l;
r <
N; ++
r)
427 <<
"l=" <<
l <<
" r=" <<
r;
434 const size_t N = 1000;
435 const size_t Q = 5000;
436 std::mt19937
rng(4242);
437 std::vector<int>
vec(
N);
439 v =
static_cast<int>(
rng() % 200);
442 for (
size_t i = 0; i <
N; ++i)
446 for (
size_t i = 0; i <
Q; ++i)
448 size_t a =
rng() %
N, b =
rng() %
N;
449 if (a > b) std::swap(a, b);
450 queries.append(std::make_pair(a, b));
456 for (
size_t i = 0; i <
Q; ++i)
462 <<
"query " << i <<
": l=" <<
l <<
" r=" <<
r;
474 auto ans =
mo.
solve({{0, 4}, {0, 0}, {2, 3}, {1, 2}});
490 std::mt19937
rng(2026);
491 std::vector<int>
vec(
N);
496 for (
size_t i = 0; i <
N; ++i)
501 for (
size_t i = 0; i < 200; ++i)
503 size_t a =
rng() %
N, b =
rng() %
N;
504 if (a > b) std::swap(a, b);
505 queries.append(std::make_pair(a, b));
511 for (
size_t i = 0; i <
queries.size(); ++i)
525 const size_t N = 5000;
526 const size_t Q = 10000;
527 std::mt19937
rng(12345);
529 std::vector<int>
vec(
N);
534 for (
size_t i = 0; i <
N; ++i)
538 for (
size_t i = 0; i <
Q; ++i)
540 size_t a =
rng() %
N, b =
rng() %
N;
541 if (a > b) std::swap(a, b);
542 queries.append(std::make_pair(a, b));
549 for (
size_t i = 0; i <
Q; ++i)
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
T & append(const T &data)
Append a copy of data
Dynamic singly linked list with functional programming support.
Offline range query engine using Mo's algorithm.
Array< answer_type > solve(const Array< std::pair< size_t, size_t > > &ranges) const
Solve queries given as (l, r) pairs.
void swap(Gen_Mo_Algorithm &other) noexcept(noexcept(std::swap(std::declval< Policy & >(), std::declval< Policy & >())))
Swap with other in O(1).
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.
std::decay_t< typename HeadC::Item_Type > T
Fw_Itor remove(Fw_Itor __first, const Fw_Itor &__last, const T &__value)
Remove elements equal to a value.
static std::atomic< bool > init
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
double add(double a, double b)
Mo's algorithm for offline range queries.