diff --git a/README b/README index 980a0d5..fd9fb4b 100644 --- a/README +++ b/README @@ -1 +1,4 @@ Hello World! + + +2026/08/14 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..daf773e --- /dev/null +++ b/main.cpp @@ -0,0 +1,18 @@ +#include +#include + +#include "segment_tree.hpp" + +int main() { + std::vector arr = {1, 3, 5, 7, 9, 11}; + + SumSegmentTree st = make_sum_segment_tree(arr); + + std::cout << "Sum of [1, 3]: " << st.query(1, 3) << '\n'; // 3 + 5 + 7 = 15 + std::cout << "Sum of [0, 5]: " << st.query(0, 5) << '\n'; // 36 + + st.update(2, 10); // arr[2]: 5 -> 10 + std::cout << "Sum of [1, 3] after update: " << st.query(1, 3) << '\n'; // 3 + 10 + 7 = 20 + + return 0; +} diff --git a/segment_tree.hpp b/segment_tree.hpp new file mode 100644 index 0000000..df9b3e9 --- /dev/null +++ b/segment_tree.hpp @@ -0,0 +1,76 @@ +#pragma once + +#include +#include + +template +class SegmentTree { +public: + SegmentTree(const std::vector& data, Op op, T identity) + : n_(static_cast(data.size())), + op_(std::move(op)), + identity_(identity), + tree_(4 * n_, identity_) { + if (n_ > 0) { + build(data, 0, 0, n_ - 1); + } + } + + T query(int left, int right) const { + return query(0, 0, n_ - 1, left, right); + } + + void update(int index, T value) { + update(0, 0, n_ - 1, index, value); + } + +private: + int n_; + Op op_; + T identity_; + std::vector tree_; + + void build(const std::vector& data, int node, int start, int end) { + if (start == end) { + tree_[node] = data[start]; + return; + } + int mid = start + (end - start) / 2; + build(data, 2 * node + 1, start, mid); + build(data, 2 * node + 2, mid + 1, end); + tree_[node] = op_(tree_[2 * node + 1], tree_[2 * node + 2]); + } + + T query(int node, int start, int end, int left, int right) const { + if (right < start || end < left) { + return identity_; + } + if (left <= start && end <= right) { + return tree_[node]; + } + int mid = start + (end - start) / 2; + return op_( + query(2 * node + 1, start, mid, left, right), + query(2 * node + 2, mid + 1, end, left, right)); + } + + void update(int node, int start, int end, int index, T value) { + if (start == end) { + tree_[node] = value; + return; + } + int mid = start + (end - start) / 2; + if (index <= mid) { + update(2 * node + 1, start, mid, index, value); + } else { + update(2 * node + 2, mid + 1, end, index, value); + } + tree_[node] = op_(tree_[2 * node + 1], tree_[2 * node + 2]); + } +}; + +using SumSegmentTree = SegmentTree>; + +inline SumSegmentTree make_sum_segment_tree(const std::vector& data) { + return SumSegmentTree(data, std::plus{}, 0LL); +} diff --git a/segment_tree_demo.exe b/segment_tree_demo.exe new file mode 100644 index 0000000..acb3fe5 Binary files /dev/null and b/segment_tree_demo.exe differ