Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
InlayHints:
Enabled: No
ParameterNames: No
DeducedTypes: No
Designators: No
6 changes: 3 additions & 3 deletions .verify-helper/timestamps.remote.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"Test/DataStructure/DisjointSparseTable_xor.test.cpp": "2024-12-27 16:29:20 +0900",
"Test/DataStructure/DynamicLiChaoTree.test.cpp": "2024-12-27 17:07:26 +0900",
"Test/DataStructure/DynamicLiChaoTree_segment.test.cpp": "2024-12-27 17:07:26 +0900",
"Test/DataStructure/DynamicSegmentTree.test.cpp": "2024-12-27 16:29:20 +0900",
"Test/DataStructure/DynamicSegmentTree_RMQ.test.cpp": "2024-12-27 16:29:20 +0900",
"Test/DataStructure/DynamicSegmentTree_RSQ.test.cpp": "2024-12-27 16:29:20 +0900",
"Test/DataStructure/DynamicSegmentTree.test.cpp": "2025-12-20 16:12:20 +0000",
"Test/DataStructure/DynamicSegmentTree_RMQ.test.cpp": "2025-12-20 16:12:20 +0000",
"Test/DataStructure/DynamicSegmentTree_RSQ.test.cpp": "2025-12-20 16:12:20 +0000",
"Test/DataStructure/LazySegmentTree_RAQRMQ.test.cpp": "2025-01-24 16:43:48 +0900",
"Test/DataStructure/LazySegmentTree_RAQRSQ.test.cpp": "2025-01-24 16:43:48 +0900",
"Test/DataStructure/LazySegmentTree_RUQRMQ.test.cpp": "2025-01-24 16:43:48 +0900",
Expand Down
97 changes: 49 additions & 48 deletions Library/DataStructure/DynamicSegmentTree.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#pragma once

#include <deque>
#include <memory>
#include <ostream>
#include <unordered_map>
#include <utility>
#include <vector>

Expand All @@ -12,72 +11,74 @@ namespace mtd {
template <monoid Monoid, int size = static_cast<int>(1e9 + 1)>
class DynamicSegmentTree {
private:
std::unordered_map<int, Monoid> m_node;
using S = decltype(Monoid().m_val);

constexpr auto _get(int i) const {
return (m_node.find(i) == m_node.end()) ? Monoid() : m_node.at(i);
}
struct Node {
Monoid val;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
Node() : val(Monoid()), left(nullptr), right(nullptr) {}
explicit Node(const Monoid& v) : val(v), left(nullptr), right(nullptr) {}
};

std::unique_ptr<Node> m_root;

template <class Lambda>
constexpr auto _update_op(int itr, Monoid&& val, const Lambda& op) {
int i = itr + size - 1;
m_node[i] = op(_get(i), std::forward<decltype(val)>(val));
while (i) {
i = (i - 1) >> 1;
m_node[i] = _get((i << 1) | 1).binaryOperation(_get((i + 1) << 1LL));
constexpr void _update_op(std::unique_ptr<Node>& node, int l, int r, int pos,
Monoid&& val, const Lambda& op) {
if (!node) node = std::make_unique<Node>();
if (r - l == 1) {
node->val = op(node->val, std::forward<Monoid>(val));
return;
}
}

constexpr auto _query(int _l, int _r) const {
_l = std::max(_l, 0);
_r = std::min(_r, size - 1);
auto l = _l + size;
int r = _r + size;
auto lm = Monoid();
auto rm = Monoid();
while (l <= r) {
if (l & 1) {
lm = lm.binaryOperation(_get(l - 1));
++l;
}
if (!(r & 1)) {
rm = _get(r - 1).binaryOperation(rm);
--r;
}
l >>= 1, r >>= 1;
int mid = l + (r - l) / 2;
if (pos < mid) {
_update_op(node->left, l, mid, pos, std::forward<Monoid>(val), op);
} else {
_update_op(node->right, mid, r, pos, std::forward<Monoid>(val), op);
}
return lm.binaryOperation(rm);
Monoid left_val = node->left ? node->left->val : Monoid();
Monoid right_val = node->right ? node->right->val : Monoid();
node->val = left_val.binaryOperation(right_val);
}

constexpr auto _construct(const std::vector<S>& vec) {
for (unsigned int i = 0; i < vec.size(); ++i) {
m_node[i + size - 1] = Monoid(vec[i]);
}
for (int i = size - 2; i >= 0; --i) {
m_node[i] = _get((i << 1) | 1).binaryOperation(_get((i + 1) << 1));
}
constexpr Monoid _query(const std::unique_ptr<Node>& node, int l, int r,
int ql, int qr) const {
if (!node || r <= ql || qr <= l) return Monoid();
if (ql <= l && r <= qr) return node->val;
int mid = l + (r - l) / 2;
return _query(node->left, l, mid, ql, qr)
.binaryOperation(_query(node->right, mid, r, ql, qr));
}

public:
constexpr DynamicSegmentTree() {}
constexpr DynamicSegmentTree() : m_root(nullptr) {}

template <class Lambda>
constexpr auto update_op(int itr, Monoid&& val, const Lambda& op) {
return _update_op(itr, std::forward<Monoid>(val), op);
constexpr auto update_op(int pos, Monoid&& val, const Lambda& op) {
return _update_op(m_root, 0, size, pos, std::forward<Monoid>(val), op);
}
constexpr auto update(int itr, Monoid&& val) {
return update_op(itr, std::forward<Monoid>(val),

constexpr auto update(int pos, Monoid&& val) {
return update_op(pos, std::forward<Monoid>(val),
[](const Monoid&, const Monoid& m2) { return m2; });
}
constexpr auto add(int itr, Monoid&& val) {
return update_op(itr, std::forward<Monoid>(val),

constexpr auto add(int pos, Monoid&& val) {
return update_op(pos, std::forward<Monoid>(val),
[](const Monoid& m1, const Monoid& m2) {
return Monoid(m1.m_val + m2.m_val);
});
}
constexpr auto query(int l, int r) const { return _query(l, r).m_val; }
constexpr auto query_all() const { return m_node[0].m_val; }

constexpr auto query(int l, int r) const {
if (l > r) return Monoid().m_val;
return _query(m_root, 0, size, l, r + 1).m_val;
}

constexpr auto query_all() const {
return m_root ? m_root->val.m_val : Monoid().m_val;
}
};

} // namespace mtd