64# ifndef TPL_MO_ALGORITHM_H
65# define TPL_MO_ALGORITHM_H
70# include <type_traits>
102 template <
typename P,
typename T>
104 size_t idx,
size_t n)
106 typename P::answer_type;
108 { p.add(data, idx) };
109 { p.remove(data, idx) };
110 { p.answer() } -> std::convertible_to<typename P::answer_type>;
139 template <
typename T,
class Policy>
210 for (
auto it =
lst.get_it(); it.has_curr(); it.next_ne())
211 data_(i++) = it.get_curr();
235 return data_.size() == 0;
240 noexcept(std::swap(std::declval<Policy &>(), std::declval<Policy &>())))
268 for (
size_t i = 0; i <
ranges.size(); ++i)
319 const size_t n =
data_.size();
320 const size_t q =
queries.size();
326 for (
size_t i = 0; i < q; ++i)
329 <<
"Gen_Mo_Algorithm::solve: query " << i
330 <<
" r=" <<
queries(i).r <<
" >= n=" << n;
332 <<
"Gen_Mo_Algorithm::solve: query " << i
335 <<
"Gen_Mo_Algorithm::solve: query " << i
336 <<
" id=" <<
queries(i).id <<
" >= q=" << q;
339 const size_t block = std::max<size_t>(1,
static_cast<size_t>(std::sqrt(
static_cast<double>(n))));
345 const size_t ba = a.
l / block;
346 const size_t bb = b.
l / block;
350 return (
ba & 1) ? (a.
r > b.
r) : (a.
r < b.
r);
369 for (
size_t i = 1; i < q; ++i)
410 template <
typename T>
427 if (++
freq[data(idx)] == 1)
433 if (--
freq[data(idx)] == 0)
451 template <
typename T>
468 const auto x =
static_cast<long long>(data(idx));
469 sum += (2 *
cnt[data(idx)] + 1) * x;
475 const auto x =
static_cast<long long>(data(idx));
477 sum -= (2 *
cnt[data(idx)] + 1) * x;
497 template <
typename T>
519 const T & x = data(idx);
534 const T & x = data(idx);
548 it.has_curr(); it.next_ne())
549 if (it.get_curr().second ==
max_freq)
561 it.has_curr(); it.next_ne())
562 if (it.get_curr().second ==
max_freq)
581 template <
typename T>
588 template <
typename T>
595 template <
typename T>
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
Dynamic singly linked list with functional programming support.
Offline range query engine using Mo's algorithm.
Array< answer_type > solve(Array< Mo_Query > queries) const
Core solver: answer all Mo_Query objects.
Array< answer_type > solve(const std::initializer_list< std::pair< size_t, size_t > > il) const
Solve queries given as (l, r) pairs (initializer list).
Gen_Mo_Algorithm(Gen_Mo_Algorithm &&) noexcept(std::is_nothrow_move_constructible_v< Array< T > > and std::is_nothrow_move_constructible_v< Policy >)=default
Gen_Mo_Algorithm(Array< T > and arr, Policy p=Policy())
Construct from an Array<T> (move).
Gen_Mo_Algorithm(const DynList< T > &lst, Policy p=Policy())
Construct from a DynList<T>.
constexpr bool is_empty() const noexcept
True if the data array is empty.
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).
Gen_Mo_Algorithm(std::initializer_list< T > il, Policy p=Policy())
Construct from an initializer list.
constexpr size_t size() const noexcept
Number of elements in the data array.
typename Policy::answer_type answer_type
Gen_Mo_Algorithm(const Array< T > &arr, Policy p=Policy())
Construct from an Array<T>.
Gen_Mo_Algorithm(const Gen_Mo_Algorithm &)=default
Concept constraining a policy for Mo's algorithm.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
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
Policy: count distinct elements in a range.
answer_type answer() const
void add(const Array< T > &data, size_t idx)
void remove(const Array< T > &data, size_t idx)
MapOLhash< T, size_t > freq
void init(const Array< T > &, size_t)
Open addressing hash map using linear probing.
typename Base::Iterator Iterator
Iterator type for traversing the map.
A query for Mo's algorithm: inclusive range [l, r] with id.
size_t id
Original query index (for reordering answers).
size_t l
Left endpoint (inclusive, 0-based).
size_t r
Right endpoint (inclusive, 0-based).
Policy: "powerful array" sum = sum(cnt[x]^2 * x).
void init(const Array< T > &, size_t)
void remove(const Array< T > &data, size_t idx)
void add(const Array< T > &data, size_t idx)
MapOLhash< T, long long > cnt
answer_type answer() const
Policy: range mode (most frequent element).
void remove(const Array< T > &data, size_t idx)
std::pair< size_t, T > answer_type
MapOLhash< T, size_t > freq
void init(const Array< T > &, size_t)
answer_type answer() const
void add(const Array< T > &data, size_t idx)
MapOLhash< size_t, size_t > cnt_of_cnt
Dynamic array container with automatic resizing.
Alias for htlist.H (DynList implementation).
Dynamic map with open hashing.