From 607736cf720f58e2218eb0ea1f772b89a09f2b73 Mon Sep 17 00:00:00 2001 From: mdonaka Date: Sun, 21 Dec 2025 00:51:37 +0900 Subject: [PATCH 1/5] chore: add clangd configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit InlayHintsを無効化するclangd設定を追加 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .clangd | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .clangd diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..928d1f9 --- /dev/null +++ b/.clangd @@ -0,0 +1,5 @@ +InlayHints: + Enabled: No + ParameterNames: No + DeducedTypes: No + Designators: No From 02fbb899b1ed4c4811cf6b7daa228b886bf3fe50 Mon Sep 17 00:00:00 2001 From: mdonaka Date: Sun, 21 Dec 2025 01:02:41 +0900 Subject: [PATCH 2/5] perf: rewrite DynamicSegmentTree with pointer-based recursive implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit unordered_mapベースの実装からポインタベースの再帰実装に変更し、性能を大幅に改善 Changes: - unordered_mapの代わりにdequeを使用してメモリ管理 - 非再帰から再帰実装に変更 - ノードを動的に作成し、ポインタで管理 Performance: - yukicoder 1282での実行時間が1422msから約100msに改善(約14倍高速化) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- Library/DataStructure/DynamicSegmentTree.hpp | 111 ++++++++++--------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/Library/DataStructure/DynamicSegmentTree.hpp b/Library/DataStructure/DynamicSegmentTree.hpp index 4987af0..fa05524 100644 --- a/Library/DataStructure/DynamicSegmentTree.hpp +++ b/Library/DataStructure/DynamicSegmentTree.hpp @@ -1,8 +1,8 @@ #pragma once #include +#include #include -#include #include #include @@ -12,72 +12,83 @@ 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; + Node* left; + Node* right; + Node() : val(Monoid()), left(nullptr), right(nullptr) {} + explicit Node(const Monoid& v) : val(v), left(nullptr), right(nullptr) {} + }; - 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)); - } + std::deque m_nodes; + 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& vec) { - for (unsigned int i = 0; i < vec.size(); ++i) { - m_node[i + size - 1] = Monoid(vec[i]); + template + 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 - constexpr auto update_op(int itr, Monoid&& val, const Lambda& op) { - return _update_op(itr, std::forward(val), op); + void update_op(int pos, const Monoid& val, const Lambda& op) { + _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(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(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 From d6caa1ed2b10ed1a7f5961ee4844ad68ad537149 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 20 Dec 2025 16:03:56 +0000 Subject: [PATCH 3/5] [auto-verifier] verify commit 02fbb899b1ed4c4811cf6b7daa228b886bf3fe50 --- .verify-helper/timestamps.remote.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index de426e9..f15f688 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-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", From 089fe96d27af83d668efd95d2c9d579a89c4627c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sat, 20 Dec 2025 16:12:20 +0000 Subject: [PATCH 4/5] refactor: use smart pointers and restore constexpr in DynamicSegmentTree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace raw pointers with std::unique_ptr for automatic memory management - Remove deque-based node storage (no longer needed with smart pointers) - Restore constexpr qualifiers to all methods - Restore Monoid&& with std::forward for move semantics optimization 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: mdonaka --- Library/DataStructure/DynamicSegmentTree.hpp | 56 ++++++++------------ 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/Library/DataStructure/DynamicSegmentTree.hpp b/Library/DataStructure/DynamicSegmentTree.hpp index fa05524..4193afc 100644 --- a/Library/DataStructure/DynamicSegmentTree.hpp +++ b/Library/DataStructure/DynamicSegmentTree.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -16,45 +15,35 @@ namespace mtd { struct Node { Monoid val; - Node* left; - Node* right; + 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::deque m_nodes; - Node* m_root; - - Node* _get_node() { - m_nodes.emplace_back(); - return &m_nodes.back(); - } - - Node* _get_node(const Monoid& val) { - m_nodes.emplace_back(val); - return &m_nodes.back(); - } + std::unique_ptr m_root; template - void _update_op(Node*& node, int l, int r, int pos, const Monoid& val, - const Lambda& op) { - if (!node) node = _get_node(); + 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, val); + node->val = op(node->val, std::forward(val)); return; } int mid = l + (r - l) / 2; if (pos < mid) { - _update_op(node->left, l, mid, pos, val, op); + _update_op(node->left, l, mid, pos, std::forward(val), op); } else { - _update_op(node->right, mid, r, pos, val, op); + _update_op(node->right, mid, r, pos, std::forward(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 { + 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; @@ -66,27 +55,28 @@ namespace mtd { constexpr DynamicSegmentTree() : m_root(nullptr) {} template - void update_op(int pos, const Monoid& val, const Lambda& op) { - _update_op(m_root, 0, size, pos, 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); } - void update(int pos, const Monoid& val) { - update_op(pos, val, - [](const Monoid&, const Monoid& m2) { return m2; }); + constexpr auto update(int pos, Monoid&& val) { + return update_op(pos, std::forward(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 pos, Monoid&& val) { + return update_op(pos, std::forward(val), + [](const Monoid& m1, const Monoid& m2) { + return Monoid(m1.m_val + m2.m_val); + }); } - S query(int l, int r) const { + 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; } - S query_all() const { + constexpr auto query_all() const { return m_root ? m_root->val.m_val : Monoid().m_val; } }; From a140f291dbe1c5ad134d68cf3c96bce0ef198c19 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 20 Dec 2025 16:13:29 +0000 Subject: [PATCH 5/5] [auto-verifier] verify commit 089fe96d27af83d668efd95d2c9d579a89c4627c --- .verify-helper/timestamps.remote.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index f15f688..48f97f7 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": "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/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",