Skip to content

Commit d3b2a0d

Browse files
committed
feat: Introduce AddGroup for flexible operations and refactor StaticRangeSum to utilize it
1 parent 348e8f2 commit d3b2a0d

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

test/static_range_sum.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ int main() {
1717
for (size_t i = 0; i < n; ++i)
1818
cin >> arr[i];
1919

20-
StaticRangeSum<uint64_t> sum(arr);
20+
StaticRangeSum<AddGroup<uint64_t>> sum(arr);
2121
while (q--) {
2222
size_t l, r;
2323
cin >> l >> r;

weilycoder/ds/group.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef WEILYCODER_GROUP_HPP
2+
#define WEILYCODER_GROUP_HPP
3+
4+
template <typename T> struct AddGroup {
5+
using value_type = T;
6+
static constexpr T operation(const T &a, const T &b) { return a + b; }
7+
static constexpr T identity() { return T{}; }
8+
static constexpr T inverse(const T &a) { return -a; }
9+
};
10+
11+
#endif

weilycoder/ds/static_range_sum.hpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,41 @@
11
#ifndef WEILYCODER_STATIC_RANGE_SUM_HPP
22
#define WEILYCODER_STATIC_RANGE_SUM_HPP
33

4+
#include "group.hpp"
45
#include <cstddef>
6+
#include <stdexcept>
57
#include <vector>
68

79
namespace weilycoder {
8-
template <typename T, typename ptr_t = size_t> struct StaticRangeSum {
10+
template <typename Group> struct StaticRangeSum {
11+
using value_type = typename Group::value_type;
12+
using T = value_type;
13+
14+
private:
915
std::vector<T> prefix_sum;
1016

11-
StaticRangeSum(const std::vector<T> &data) : prefix_sum(data.size() + 1) {
12-
for (ptr_t i = 1; i <= data.size(); ++i)
13-
prefix_sum[i] = prefix_sum[i - 1] + data[i - 1];
17+
public:
18+
explicit StaticRangeSum(const std::vector<T> &data)
19+
: prefix_sum(data.size() + 1, Group::identity()) {
20+
for (size_t i = 1; i <= data.size(); ++i)
21+
prefix_sum[i] = Group::operation(prefix_sum[i - 1], data[i - 1]);
22+
}
23+
24+
template <typename InputIt>
25+
StaticRangeSum(InputIt first, InputIt last)
26+
: prefix_sum(std::distance(first, last) + 1, Group::identity()) {
27+
size_t i = 1;
28+
for (auto it = first; it != last; ++it, ++i)
29+
prefix_sum[i] = Group::operation(prefix_sum[i - 1], *it);
1430
}
1531

16-
T query(ptr_t l, ptr_t r) const { return prefix_sum[r] - prefix_sum[l]; }
32+
size_t size() const { return prefix_sum.size() - 1; }
33+
34+
T query(size_t l, size_t r) const {
35+
if (l > r || r > size())
36+
throw std::out_of_range("Invalid range for StaticRangeSum query");
37+
return Group::operation(Group::inverse(prefix_sum[l]), prefix_sum[r]);
38+
}
1739
};
1840
} // namespace weilycoder
1941

0 commit comments

Comments
 (0)