69# ifndef TPL_SPARSE_TABLE_H
70# define TPL_SPARSE_TABLE_H
77# include <initializer_list>
78# include <type_traits>
90 namespace sparse_table_detail
100 template <
typename U>
102 template <
typename U>
104 template <
typename U>
106 template <
typename U>
108 template <
typename U>
110 template <
typename U>
112 template <
typename U>
114 template <
typename U>
116 template <
typename U>
136 template <
typename F,
typename T>
138 sparse_table_detail::is_arithmetic_functor<std::remove_cvref_t<F>>
and
139 std::is_arithmetic_v<std::remove_cv_t<T>>
and
140 not std::is_same_v<std::remove_cv_t<T>,
bool>;
155 template <
typename F,
typename T>
167 template <
typename F,
typename T>
177 template <std::totally_ordered T>
182 return a <= b ? a : b;
193 template <std::totally_ordered T>
198 return a >= b ? a : b;
232 template <
typename T,
class Op>
244 T &
at(
const size_t k,
const size_t i) {
return table(
k *
n + i); }
245 const T &
at(
const size_t k,
const size_t i)
const {
return table(
k *
n + i); }
250 return nn == 0 ? 0 :
static_cast<size_t>(std::bit_width(
nn));
268 for (
size_t i = 2; i <=
n; ++i)
278 const size_t half =
size_t{1} << (
k - 1);
279 const size_t limit =
n - (
size_t{1} <<
k) + 1;
280 for (
size_t i = 0; i <
limit; ++i)
286 template <
class Getter>
290 for (
size_t i = 0; i <
n; ++i)
297 template <
class AlephIt>
301 for (; it.has_curr(); it.next_ne())
302 at(0, i++) = it.get_curr();
343 auto it =
il.begin();
416 <<
"Gen_Sparse_Table::query: r=" <<
r <<
" >= n=" <<
n;
418 <<
"Gen_Sparse_Table::query: l=" <<
l <<
" > r=" <<
r;
421 return op(
at(
k,
l),
at(
k,
r - (
size_t{1} <<
k) + 1));
434 <<
"Gen_Sparse_Table::get: index " << i <<
" >= size " <<
n;
458 for (
size_t i = 0; i <
n; ++i)
492 template <std::totally_ordered T>
517 template <std::totally_ordered T>
C++20 concepts hub: comparison, BST policy, and Aleph container concepts.
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.
Standard functor implementations and comparison objects.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
void swap(Array &s) noexcept
Swap this with s
Doubly-linked list (defined in tpl_dynList.H).
Sparse Table over an arbitrary associative and idempotent binary operation.
void build_upper_levels()
Build levels k >= 1 from already-populated level 0.
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).
Array< T > values() const
Reconstruct all original values into an Array.
void fill_and_build(Getter getter)
Fill level 0 from a 0-based indexed getter and build higher levels.
constexpr size_t size() const noexcept
Number of logical elements.
Gen_Sparse_Table(std::initializer_list< T > il, Op oper=Op())
Construct from an initializer list in O(n log n) time.
Gen_Sparse_Table(const std::vector< T > &values, Op oper=Op())
Construct from a std::vector<T> in O(n log n) time.
static constexpr size_t compute_cells(const size_t nn) noexcept
Number of flattened cells needed to store all levels.
T & at(const size_t k, const size_t i)
Access table[k][i] (0-based row k, 0-based column i).
void fill_from_aleph_it(AlephIt it)
Fill level 0 from an Aleph-style iterator and build higher levels.
Gen_Sparse_Table(const size_t num, const T &init_val, Op oper=Op())
Construct a sparse table with num elements, all equal to init_val.
Gen_Sparse_Table(const Gen_Sparse_Table &)=default
const T & at(const size_t k, const size_t i) const
static constexpr size_t compute_levels(const size_t nn) noexcept
Compute levels = floor(log2(n)) + 1; 0 if n == 0.
constexpr bool is_empty() const noexcept
True if the table contains no elements.
Gen_Sparse_Table(const DynList< T > &values, Op oper=Op())
Construct from a DynList<T> in O(n log n) time.
T query(const size_t l, const size_t r) const
Range query over [l, r] in O(1).
T Item_Type
The type of the element stored in the table.
void swap(Gen_Sparse_Table &other) noexcept
Swap this table with other in O(1).
Gen_Sparse_Table(Gen_Sparse_Table &&) noexcept(std::is_nothrow_move_constructible_v< Array< T > > &&std::is_nothrow_move_constructible_v< Op >)=default
void build_log_table()
Precompute the log lookup table for lengths [0..n].
Gen_Sparse_Table(const Array< T > &values, Op oper=Op())
Construct from an Array<T> in O(n log n) time.
A binary functor closed over T.
A closed binary operation not known to break idempotency.
Binary operation compatible with Sparse Table queries.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
constexpr bool is_arithmetic_functor
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
constexpr bool is_known_non_idempotent_op
True if F is known not to be idempotent over T.
Functor returning the maximum of two values.
constexpr T operator()(const T &a, const T &b) const noexcept
Sparse Table for range maximum queries.
Functor returning the minimum of two values.
constexpr T operator()(const T &a, const T &b) const noexcept
Sparse Table for range minimum queries.
Dynamic array container with automatic resizing.
Alias for htlist.H (DynList implementation).