diff --git a/.clangd b/.clangd new file mode 100644 index 00000000..928d1f95 --- /dev/null +++ b/.clangd @@ -0,0 +1,5 @@ +InlayHints: + Enabled: No + ParameterNames: No + DeducedTypes: No + Designators: No diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index de426e96..48f97f7c 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -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", diff --git a/Library/DataStructure/DynamicSegmentTree.hpp b/Library/DataStructure/DynamicSegmentTree.hpp index 4987af08..4193afc7 100644 --- a/Library/DataStructure/DynamicSegmentTree.hpp +++ b/Library/DataStructure/DynamicSegmentTree.hpp @@ -1,8 +1,7 @@ #pragma once -#include +#include #include -#include #include #include @@ -12,72 +11,74 @@ namespace mtd { template (1e9 + 1)> class DynamicSegmentTree { private: - std::unordered_map 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 left; + std::unique_ptr right; + Node() : val(Monoid()), left(nullptr), right(nullptr) {} + explicit Node(const Monoid& v) : val(v), left(nullptr), right(nullptr) {} + }; + + std::unique_ptr m_root; template - constexpr auto _update_op(int itr, Monoid&& val, const Lambda& op) { - int i = itr + size - 1; - m_node[i] = op(_get(i), std::forward(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, int l, int r, int pos, + Monoid&& val, const Lambda& op) { + if (!node) node = std::make_unique(); + if (r - l == 1) { + node->val = op(node->val, std::forward(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(val), op); + } else { + _update_op(node->right, mid, r, pos, std::forward(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& 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, 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 - constexpr auto update_op(int itr, Monoid&& val, const Lambda& op) { - return _update_op(itr, std::forward(val), op); + constexpr auto update_op(int pos, Monoid&& val, const Lambda& op) { + return _update_op(m_root, 0, size, pos, std::forward(val), op); } - constexpr auto update(int itr, Monoid&& val) { - return update_op(itr, std::forward(val), + + constexpr auto update(int pos, Monoid&& val) { + return update_op(pos, std::forward(val), [](const Monoid&, const Monoid& m2) { return m2; }); } - constexpr auto add(int itr, Monoid&& val) { - return update_op(itr, std::forward(val), + + constexpr auto add(int pos, Monoid&& val) { + return update_op(pos, std::forward(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