11#pragma once
22
3- #include < deque >
3+ #include < memory >
44#include < ostream>
5- #include < unordered_map>
65#include < utility>
76#include < vector>
87
@@ -12,72 +11,74 @@ namespace mtd {
1211 template <monoid Monoid, int size = static_cast <int >(1e9 + 1 )>
1312 class DynamicSegmentTree {
1413 private:
15- std::unordered_map<int , Monoid> m_node;
1614 using S = decltype (Monoid().m_val);
1715
18- constexpr auto _get (int i) const {
19- return (m_node.find (i) == m_node.end ()) ? Monoid () : m_node.at (i);
20- }
16+ struct Node {
17+ Monoid val;
18+ std::unique_ptr<Node> left;
19+ std::unique_ptr<Node> right;
20+ Node () : val(Monoid()), left(nullptr ), right(nullptr ) {}
21+ explicit Node (const Monoid& v) : val(v), left(nullptr ), right(nullptr ) {}
22+ };
23+
24+ std::unique_ptr<Node> m_root;
2125
2226 template <class Lambda >
23- constexpr auto _update_op (int itr, Monoid&& val, const Lambda& op) {
24- int i = itr + size - 1 ;
25- m_node[i] = op ( _get (i), std::forward< decltype (val)>(val) );
26- while (i ) {
27- i = (i - 1 ) >> 1 ;
28- m_node[i] = _get ((i << 1 ) | 1 ). binaryOperation ( _get ((i + 1 ) << 1LL )) ;
27+ constexpr void _update_op (std::unique_ptr<Node>& node, int l, int r, int pos,
28+ Monoid&& val, const Lambda& op) {
29+ if (!node) node = std::make_unique<Node>( );
30+ if (r - l == 1 ) {
31+ node-> val = op (node-> val , std::forward<Monoid>(val)) ;
32+ return ;
2933 }
30- }
31-
32- constexpr auto _query (int _l, int _r) const {
33- _l = std::max (_l, 0 );
34- _r = std::min (_r, size - 1 );
35- auto l = _l + size;
36- int r = _r + size;
37- auto lm = Monoid ();
38- auto rm = Monoid ();
39- while (l <= r) {
40- if (l & 1 ) {
41- lm = lm.binaryOperation (_get (l - 1 ));
42- ++l;
43- }
44- if (!(r & 1 )) {
45- rm = _get (r - 1 ).binaryOperation (rm);
46- --r;
47- }
48- l >>= 1 , r >>= 1 ;
34+ int mid = l + (r - l) / 2 ;
35+ if (pos < mid) {
36+ _update_op (node->left , l, mid, pos, std::forward<Monoid>(val), op);
37+ } else {
38+ _update_op (node->right , mid, r, pos, std::forward<Monoid>(val), op);
4939 }
50- return lm.binaryOperation (rm);
40+ Monoid left_val = node->left ? node->left ->val : Monoid ();
41+ Monoid right_val = node->right ? node->right ->val : Monoid ();
42+ node->val = left_val.binaryOperation (right_val);
5143 }
5244
53- constexpr auto _construct (const std::vector<S >& vec) {
54- for ( unsigned int i = 0 ; i < vec. size (); ++i) {
55- m_node[i + size - 1 ] = Monoid (vec[i] );
56- }
57- for ( int i = size - 2 ; i >= 0 ; --i) {
58- m_node[i] = _get ((i << 1 ) | 1 ). binaryOperation ( _get ((i + 1 ) << 1 ));
59- }
45+ constexpr Monoid _query (const std::unique_ptr<Node >& node, int l, int r,
46+ int ql, int qr) const {
47+ if (!node || r <= ql || qr <= l) return Monoid ();
48+ if (ql <= l && r <= qr) return node-> val ;
49+ int mid = l + (r - l) / 2 ;
50+ return _query (node-> left , l, mid, ql, qr)
51+ . binaryOperation ( _query (node-> right , mid, r, ql, qr));
6052 }
6153
6254 public:
63- constexpr DynamicSegmentTree () {}
55+ constexpr DynamicSegmentTree () : m_root( nullptr ) {}
6456
6557 template <class Lambda >
66- constexpr auto update_op (int itr , Monoid&& val, const Lambda& op) {
67- return _update_op (itr , std::forward<Monoid>(val), op);
58+ constexpr auto update_op (int pos , Monoid&& val, const Lambda& op) {
59+ return _update_op (m_root, 0 , size, pos , std::forward<Monoid>(val), op);
6860 }
69- constexpr auto update (int itr, Monoid&& val) {
70- return update_op (itr, std::forward<Monoid>(val),
61+
62+ constexpr auto update (int pos, Monoid&& val) {
63+ return update_op (pos, std::forward<Monoid>(val),
7164 [](const Monoid&, const Monoid& m2) { return m2; });
7265 }
73- constexpr auto add (int itr, Monoid&& val) {
74- return update_op (itr, std::forward<Monoid>(val),
66+
67+ constexpr auto add (int pos, Monoid&& val) {
68+ return update_op (pos, std::forward<Monoid>(val),
7569 [](const Monoid& m1, const Monoid& m2) {
7670 return Monoid (m1.m_val + m2.m_val );
7771 });
7872 }
79- constexpr auto query (int l, int r) const { return _query (l, r).m_val ; }
80- constexpr auto query_all () const { return m_node[0 ].m_val ; }
73+
74+ constexpr auto query (int l, int r) const {
75+ if (l > r) return Monoid ().m_val ;
76+ return _query (m_root, 0 , size, l, r + 1 ).m_val ;
77+ }
78+
79+ constexpr auto query_all () const {
80+ return m_root ? m_root->val .m_val : Monoid ().m_val ;
81+ }
8182 };
8283
8384} // namespace mtd
0 commit comments