Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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-21 01:02:41 +0900",
"Test/DataStructure/DynamicSegmentTree_RMQ.test.cpp": "2025-12-21 01:02:41 +0900",
"Test/DataStructure/DynamicSegmentTree_RSQ.test.cpp": "2025-12-21 01:02:41 +0900",
"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
111 changes: 61 additions & 50 deletions Library/DataStructure/DynamicSegmentTree.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

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

Expand All @@ -12,72 +12,83 @@ 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;
Node* left;
Node* right;
Node() : val(Monoid()), left(nullptr), right(nullptr) {}
explicit Node(const Monoid& v) : val(v), left(nullptr), right(nullptr) {}
};

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));
}
std::deque<Node> m_nodes;
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これvectorで良い

Node* m_root;

Node* _get_node() {
m_nodes.emplace_back();
return &m_nodes.back();
}

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;
}
return lm.binaryOperation(rm);
Node* _get_node(const Monoid& val) {
m_nodes.emplace_back(val);
return &m_nodes.back();
}

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]);
template <class Lambda>
void _update_op(Node*& node, int l, int r, int pos, const Monoid& val,
const Lambda& op) {
if (!node) node = _get_node();
if (r - l == 1) {
node->val = op(node->val, val);
return;
}
for (int i = size - 2; i >= 0; --i) {
m_node[i] = _get((i << 1) | 1).binaryOperation(_get((i + 1) << 1));
int mid = l + (r - l) / 2;
if (pos < mid) {
_update_op(node->left, l, mid, pos, val, op);
} else {
_update_op(node->right, mid, r, pos, val, op);
}
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);
}

Monoid _query(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);
void update_op(int pos, const Monoid& val, const Lambda& op) {
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monoid&&const Monoid& valにしたのはなぜ?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constexpr消さず全部付け直して

_update_op(m_root, 0, size, pos, val, op);
}

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

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

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

S query_all() const {
return m_root ? m_root->val.m_val : Monoid().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; }
};

} // namespace mtd