GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 57
Functions: -% 0 / 0 / 0
Branches: -% 0 / 0 / 0

bit.hpp
Line Branch Exec Source
1 #pragma once
2
3 #include <vector>
4 #include <cassert>
5
6 /** Binary-indexed tree
7 *
8 * A binary indexed tree with N nodes of type T provides the
9 * following two functions for 0 <= i <= N:
10 *
11 * prefix(int i) -> prefix_iterator<T>
12 * suffix(int i) -> suffix_iterator<T>
13 *
14 * such that size(suffix(i) intersect prefix(j)) = (1 if i < j else 0).
15 * Furthermore, the resulting lists always have size at most log_2(N).
16 *
17 * This can be used to implement either point-update/(prefix|suffix)-query or
18 * (prefix|suffix)-update/point-query over a virtual array of size N of a
19 * commutative monoid. This can be generalized to implement
20 * point-update/range-query or range-update/point-query over a virtual array
21 * of size N of a commutative group.
22 *
23 * With 0-indexed data, prefixes are more natural:
24 * * For range update/query, use for_prefix for the ranges and for_suffix for the points.
25 * * For prefix update/query, no change.
26 * * For suffix update/query, use for_prefix(point + 1); 1-index the data.
27 */
28 template <typename T> class binary_indexed_tree {
29 private:
30 std::vector<T> dat;
31 public:
32 binary_indexed_tree() {}
33 explicit binary_indexed_tree(size_t N) : dat(N) {}
34 binary_indexed_tree(size_t N, const T& t) : dat(N, t) {}
35
36 size_t size() const { return dat.size(); }
37 const std::vector<T>& data() const { return dat; }
38 std::vector<T>& data() { return dat; }
39
40 private:
41 template <typename I, typename S = I> struct iterator_range {
42 private:
43 I begin_;
44 S end_;
45 public:
46 iterator_range() : begin_(), end_() {}
47 iterator_range(const I& begin__, const S& end__) : begin_(begin__), end_(end__) {}
48 iterator_range(I&& begin__, S&& end__) : begin_(begin__), end_(end__) {}
49 I begin() const { return begin_; }
50 S end() const { return end_; }
51 };
52
53 public:
54 class const_suffix_iterator {
55 private:
56 const T* dat;
57 int a;
58 const_suffix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
59 friend class binary_indexed_tree;
60 public:
61 friend bool operator != (const const_suffix_iterator& i, const const_suffix_iterator& j) {
62 assert(j.dat == nullptr);
63 return i.a < j.a;
64 }
65 const_suffix_iterator& operator ++ () {
66 a |= a+1;
67 return *this;
68 }
69 const T& operator * () const {
70 return dat[a];
71 }
72 };
73 using const_suffix_range = iterator_range<const_suffix_iterator>;
74 const_suffix_range suffix(int a) const {
75 assert(0 <= a && a <= int(dat.size()));
76 return const_suffix_range{const_suffix_iterator{dat.data(), a}, const_suffix_iterator{nullptr, int(dat.size())}};
77 }
78
79 class suffix_iterator {
80 private:
81 T* dat;
82 int a;
83 suffix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
84 friend class binary_indexed_tree;
85 public:
86 friend bool operator != (const suffix_iterator& i, const suffix_iterator& j) {
87 assert(j.dat == nullptr);
88 return i.a < j.a;
89 }
90 suffix_iterator& operator ++ () {
91 a |= a+1;
92 return *this;
93 }
94 T& operator * () const {
95 return dat[a];
96 }
97 };
98 using suffix_range = iterator_range<suffix_iterator>;
99 suffix_range suffix(int a) {
100 assert(0 <= a && a <= int(dat.size()));
101 return suffix_range{suffix_iterator{dat.data(), a}, suffix_iterator{nullptr, int(dat.size())}};
102 }
103
104 class const_prefix_iterator {
105 private:
106 const T* dat;
107 int a;
108 const_prefix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
109 friend class binary_indexed_tree;
110 public:
111 friend bool operator != (const const_prefix_iterator& i, const const_prefix_iterator& j) {
112 assert(j.dat == nullptr);
113 return i.a > 0;
114 }
115 const_prefix_iterator& operator ++ () {
116 a &= a-1;
117 return *this;
118 }
119 const T& operator * () const {
120 return dat[a-1];
121 }
122 };
123 using const_prefix_range = iterator_range<const_prefix_iterator>;
124 const_prefix_range prefix(int a) const {
125 return const_prefix_range{const_prefix_iterator{dat.data(), a}, const_prefix_iterator{nullptr, 0}};
126 }
127
128 class prefix_iterator {
129 private:
130 T* dat;
131 int a;
132 prefix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
133 friend class binary_indexed_tree;
134 public:
135 friend bool operator != (const prefix_iterator& i, const prefix_iterator& j) {
136 assert(j.dat == nullptr);
137 return i.a > 0;
138 }
139 prefix_iterator& operator ++ () {
140 a &= a-1;
141 return *this;
142 }
143 T& operator * () const {
144 return dat[a-1];
145 }
146 };
147 using prefix_range = iterator_range<prefix_iterator>;
148 prefix_range prefix(int a) {
149 return prefix_range{prefix_iterator{dat.data(), a}, prefix_iterator{nullptr, 0}};
150 }
151 };
152