Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
segtree_dynamic.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
3/// @brief 動的セグ木
4template<typename Monoid>
6 using Type=typename Monoid::Type;
7
8 /// @brief サイズ mx の動的セグ木を宣言する
9 SegTreeDynamic(ll mx=1e9, int q=5e5) {
10 this->mx=mx;
11 node.reserve(q);
12 node.push_back(Node(0,mx));
13 route.reserve(100);
14 }
15
16 /// @brief i 番目の要素を v に変える
17 void set(ll i, Type v) {
18 ll left=0,right=mx,cur=0;
19 route.clear();
20 while(left<right-1) {
21 ll mid=(left+right)/2;
22
23 int nxt,toi;
24 if(i<mid) nxt=node[cur].to[0],toi=0; //左
25 else nxt=node[cur].to[1],toi=1; //右
26
27 if(nxt==-1) {
28 nxt=node.size();
29 node[cur].to[toi]=nxt;
30
31 if(toi==0) node.push_back(Node(left,mid));
32 else node.push_back(Node(mid,right));
33 }
34
35 if(i<mid) right=mid;
36 else left=mid;
37
38 route.push_back(cur);
39 cur=nxt;
40 }
41 reverse(ALL(route));
42 node[cur].value=v;
43
44 for(int r:route) {
45 int leftc=node[r].to[0],rightc=node[r].to[1];
46 Type leftv=(leftc==-1 ? Monoid::id() : node[leftc].value);
47 Type rightv=(rightc==-1 ? Monoid::id() : node[rightc].value);
48 node[r].value=Monoid::op(leftv,rightv);
49 }
50 }
51
52 /// @brief 区間 [l, r) のモノイド積を返す
53 Type fold(ll l, ll r, int idx, ll left, ll right) {
54 if(right<l||left>r) return Monoid::id();
55 if(l<=left&&right<=r) return node[idx].value;
56
57 ll mid=(left+right)/2;
58 int leftc=node[idx].to[0],rightc=node[idx].to[1];
59
60 Type leftv,rightv;
61 if(leftc==-1) leftv=Monoid::id();
62 else leftv=fold(l,r,leftc,left,mid);
63 if(rightc==-1) rightv=Monoid::id();
64 else rightv=fold(l,r,rightc,mid,right);
65
66 return Monoid::op(leftv,rightv);
67 }
68 Type fold(ll l, ll r) { return fold(l,r,0,0,mx); }
69
70 Type operator[](ll i) { return fold(i,i+1); }
71
72private:
73 struct Node {
74 Type value;
75 array<int,2> to;
76 ll left,right;
77 Node(ll l, ll r) {
78 to.fill(-1);
79 left=l; right=r;
80 value=Monoid::id();
81 }
82 };
83 vector<Node> node;
84 ll mx=1e9;
85 vector<int> route;
86};
87
88#include"../../kyopro_library/others/monoid.hpp"
89
90/// @brief 区間クエリ
91namespace RangeQuery {
92 /// @brief 1点変更 / 区間 min
93 template<typename T, T max_value=INF>
94 struct MinDynamic { using Type=struct SegTreeDynamic<Monoid::Min<T,max_value>>; };
95
96 /// @brief 1点変更 / 区間 max
97 template<typename T, T min_value=-INF>
98 struct MaxDynamic { using Type=struct SegTreeDynamic<Monoid::Max<T,min_value>>; };
99
100 /// @brief 1点変更 / 区間和
101 template<typename T>
102 struct SumDynamic { using Type=struct SegTreeDynamic<Monoid::Sum<T>>; };
103}
モノイド
Definition monoid.hpp:5
区間クエリ
Definition segtree.hpp:136
1点変更 / 区間 max
1点変更 / 区間 min
1点変更 / 区間和
動的セグ木
SegTreeDynamic(ll mx=1e9, int q=5e5)
サイズ mx の動的セグ木を宣言する
Type fold(ll l, ll r, int idx, ll left, ll right)
区間 [l, r) のモノイド積を返す
Type operator[](ll i)
void set(ll i, Type v)
i 番目の要素を v に変える
Type fold(ll l, ll r)
const int INF
Definition template.hpp:13
#define ALL(x)
Definition template.hpp:4