67# ifndef TPL_FENWICK_TREE_H
68# define TPL_FENWICK_TREE_H
73# include <initializer_list>
74# include <type_traits>
91 std::is_arithmetic_v<T> &&
92 std::totally_ordered<T> &&
93 std::is_signed_v<T> &&
94 !std::same_as<T, bool>;
102 template <
typename F,
typename T>
135 template <
typename T,
153 static constexpr size_t lowbit(
size_t x)
noexcept
162 for (
size_t i = 1; i <= n; ++i)
163 if (
const size_t parent = i + lowbit(i); parent <= n)
164 tree(parent) = plus_op(tree(parent), tree(i));
171 for (
size_t i = 0; i < n; ++i)
177 template <
class StdIt>
181 for (; first != last; ++first)
187 template <
class AlephIt>
191 for (; it.has_curr(); it.next_ne())
192 tree(i++) = it.get_curr();
209 : tree(num + 1,
T()), n(num),
210 plus_op(pop), minus_op(
mop)
226 plus_op(pop), minus_op(
mop)
228 fill_from_std_iter(
il.begin(),
il.end());
239 : tree(values.
size() + 1,
T()), n(values.
size()),
240 plus_op(pop), minus_op(
mop)
242 fill_from_indexed([&values](
size_t i) {
return values(i); });
256 : tree(values.
size() + 1,
T()), n(values.
size()),
257 plus_op(pop), minus_op(
mop)
259 fill_from_indexed([&values](
size_t i) {
return values[i]; });
270 : tree(values.
size() + 1,
T()), n(values.
size()),
271 plus_op(pop), minus_op(
mop)
273 fill_from_aleph_it(values.
get_it());
293 <<
"Gen_Fenwick_Tree::update: index " << i <<
" >= size " << n;
295 for (++i; i <= n; i += i & (-i))
296 tree(i) = plus_op(tree(i), delta);
308 <<
"Gen_Fenwick_Tree::prefix: index " << i <<
" >= size " << n;
311 for (++i; i > 0; i -= i & (-i))
312 s = plus_op(s, tree(i));
326 <<
"Gen_Fenwick_Tree::query: r=" <<
r <<
" >= n=" << n;
328 <<
"Gen_Fenwick_Tree::query: l=" <<
l <<
" > r=" <<
r;
355 update(i, minus_op(
value, get(i)));
371 for (
size_t i = 0; i < n; ++i)
380 std::swap(n,
other.n);
381 std::swap(plus_op,
other.plus_op);
382 std::swap(minus_op,
other.minus_op);
406 template <FenwickArithmetic T>
430 const size_t nn = this->
n;
448 return pos <
nn ? pos :
nn;
492 template <FenwickArithmetic T>
502 return static_cast<T>(i + 1) *
b1.prefix(i) -
b2.prefix(i);
510 for (
size_t i = 1; i <
n; ++i)
511 d2(i) = d(i) *
static_cast<T>(i);
524 :
b1(num),
b2(num),
n(num)
544 auto it =
il.begin();
547 for (
size_t i = 1; i <
n; ++i, ++it)
567 for (
size_t i = 1; i <
n; ++i)
591 <<
"Range_Fenwick_Tree::update: l=" <<
l <<
" > r=" <<
r;
593 <<
"Range_Fenwick_Tree::update: r=" <<
r <<
" >= size " <<
n;
596 b2.update(
l, delta *
static_cast<T>(
l));
602 b2.update(
r + 1,
neg *
static_cast<T>(
r + 1));
624 <<
"Range_Fenwick_Tree::prefix: index " << i <<
" >= size " <<
n;
639 <<
"Range_Fenwick_Tree::query: r=" <<
r <<
" >= n=" <<
n;
641 <<
"Range_Fenwick_Tree::query: l=" <<
l <<
" > r=" <<
r;
677 for (
size_t i = 0; i <
n; ++i)
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.
size_t size_t int32_t value
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).
Fenwick tree over an arbitrary abelian group.
void fill_from_std_iter(StdIt first, StdIt last)
Fill the internal storage from a standard iterator range and build.
Array< T > values() const
Reconstruct all original values into an Array.
T query(const size_t l, const size_t r) const
Range query: Plus(a[l], a[l+1], ..., a[r]).
constexpr bool is_empty() const noexcept
True if the tree contains no elements.
Gen_Fenwick_Tree(const DynList< T > &values, Plus pop=Plus(), Minus mop=Minus())
Construct from a DynList<T> in O(n) time.
void set(const size_t i, const T &value)
Set a[i] = value.
void fill_from_aleph_it(AlephIt it)
Fill the internal storage from an Aleph-style iterator (get_it()) and build.
void swap(Gen_Fenwick_Tree &other) noexcept
Swap this tree with other in O(1).
T prefix(size_t i) const
Prefix query: Plus(a[0], a[1], ..., a[i]).
T get(const size_t i) const
Retrieve the logical value a[i].
void build()
O(n) bottom-up construction of the tree array from raw values already placed in tree[1....
Gen_Fenwick_Tree(const Gen_Fenwick_Tree &)=default
Gen_Fenwick_Tree(const size_t num, Plus pop=Plus(), Minus mop=Minus())
Construct a tree with num elements, all equal to the identity T().
static constexpr size_t lowbit(size_t x) noexcept
Return the least significant set bit of x (as a mask).
void fill_from_indexed(F getter)
Fill the internal storage from a 0-based indexed getter and build.
T Item_Type
The type of element stored in the tree.
Gen_Fenwick_Tree(Gen_Fenwick_Tree &&) noexcept=default
Gen_Fenwick_Tree(const Array< T > &values, Plus pop=Plus(), Minus mop=Minus())
Construct from an Array<T> in O(n) time.
Gen_Fenwick_Tree(std::initializer_list< T > il, Plus pop=Plus(), Minus mop=Minus())
Construct from an initializer list in O(n) time.
Gen_Fenwick_Tree(const std::vector< T > &values, Plus pop=Plus(), Minus mop=Minus())
Construct from a std::vector<T> in O(n) time.
constexpr size_t size() const noexcept
Number of logical elements.
Fenwick tree supporting range updates and range queries.
void build_from_diffs(const Array< T > &d)
Rebuild b1 and b2 from a difference array stored in d.
void point_update(const size_t i, const T &delta)
Point update: add delta to a[i].
Range_Fenwick_Tree(const size_t num)
Construct a tree with num elements, all zero.
void update(size_t l, const size_t r, const T &delta)
Range update: add delta to every a[i] with l <= i <= r.
constexpr bool is_empty() const noexcept
True if the tree contains no elements.
Range_Fenwick_Tree(Range_Fenwick_Tree &&) noexcept=default
void swap(Range_Fenwick_Tree &other) noexcept
Swap this tree with other in O(1).
T get(const size_t i) const
Retrieve the logical value a[i].
void set(const size_t i, const T &value)
Set a[i] = value.
Range_Fenwick_Tree(const Array< T > &values)
Construct from an Array<T> in O(n) time.
Range_Fenwick_Tree(std::initializer_list< T > il)
Construct from an initializer list in O(n) time.
Range_Fenwick_Tree(const Range_Fenwick_Tree &)=default
Array< T > values() const
Reconstruct all original values into an Array.
T prefix(const size_t i) const
Prefix query: sum of a[0..i].
constexpr size_t size() const noexcept
Number of logical elements.
T query(const size_t l, const size_t r) const
Range query: sum of a[l..r].
T prefix_sum(size_t i) const
Internal: prefix sum P(i) = (i+1)*B1.prefix(i) - B2.prefix(i)
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
A binary functor closed over T.
Arithmetic domain accepted by Fenwick specializations.
Binary operation compatible with Fenwick tree group functors.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Main namespace for Aleph-w library functions.
size_t size(Node *root) noexcept
std::decay_t< typename HeadC::Item_Type > T
static void prefix(Node *root, DynList< Node * > &acc)
void next()
Advance all underlying iterators (bounds-checked).
Fenwick tree for arithmetic types with find_kth support.
size_t find_kth(T k) const
Find the smallest 0-based index i such that prefix(i) >= k.
Dynamic array container with automatic resizing.
Alias for htlist.H (DynList implementation).