1
- template <typename T>
2
- struct Data {
1
+ template <typename T> struct Data {
3
2
// set default values
4
3
T sum = 0 ;
5
4
T mx = 0 ;
@@ -16,92 +15,95 @@ struct Data {
16
15
}
17
16
};
18
17
19
- template <typename T>
20
- class NodeST {
21
- public:
18
+ template <typename T> class NodeST {
19
+ public:
22
20
NodeST<T> *left, *right;
23
21
int low, high;
24
22
Data<T> data;
25
23
NodeST () : left(NULL ), right(NULL ), data(Data<T>()) {}
26
24
NodeST (Data<T> v) : left(NULL ), right(NULL ), data(v) {}
27
- NodeST (NodeST* l, NodeST* r, Data<T> v) : left(l), right(r), data(v) {}
25
+ NodeST (NodeST * l, NodeST * r, Data<T> v) : left(l), right(r), data(v) {}
28
26
};
29
27
30
- template <typename T>
31
- class PersistentSegmentTree {
32
- public:
33
- void build (NodeST<T>* node, const vector<T> &v, int low, int high) {
34
- if (low == high) return node->data .apply (low, v[low]);
35
- int mid = low + (high - low)/ 2 ;
36
- node->left = new NodeST<T>();
37
- node->right = new NodeST<T>();
38
- build (node->left , v, low, mid);
39
- build (node->right , v, mid+ 1 , high);
28
+ template <typename T> class PersistentSegmentTree {
29
+ public:
30
+ void build (NodeST<T> *node, const vector<T> &v, int low, int high) {
31
+ if ( low == high)
32
+ return node->data .apply (low, v[low]);
33
+ int mid = low + (high - low) / 2 ;
34
+ node->left = new NodeST<T>();
35
+ node->right = new NodeST<T>();
36
+ build (node->left , v, low, mid);
37
+ build (node->right , v, mid + 1 , high);
40
38
pull (node);
41
39
}
42
40
inline Data<T> unite (const Data<T> &a, const Data<T> &b) {
43
41
Data<T> res;
44
42
res.sum = a.sum + b.sum ;
45
43
res.mx = max (a.mx , b.mx );
46
44
res.mn = min (a.mn , b.mn );
47
- res.idx_mn = (res.mn == a.mn ? a.idx_mn : b.idx_mn );
48
- res.idx_mx = (res.mx == a.mx ? a.idx_mx : b.idx_mx );
45
+ res.idx_mn = (res.mn == a.mn ? a.idx_mn : b.idx_mn );
46
+ res.idx_mx = (res.mx == a.mx ? a.idx_mx : b.idx_mx );
49
47
return res;
50
48
}
51
49
inline void pull (NodeST<T> *node) {
52
50
node->data = unite (node->left ->data , node->right ->data );
53
51
}
54
- void upgrade (NodeST<T>* prev, NodeST<T>* current, int low, int high, int idx, int value) {
55
- if (idx > high || idx < low || low > high) return ;
56
- if (low == high) return current->data .apply (low, value);
57
- int mid = low + (high - low)/2 ;
58
- if (idx <= mid) {
59
- current->right = prev->right ;
60
- current->left = new NodeST<T>(prev->left ->data );
61
- upgrade (prev->left , current->left , low, mid, idx, value);
62
- } else {
63
- current->left = prev->left ;
64
- current->right = new NodeST<T>(prev->right ->data );
65
- upgrade (prev->right , current->right , mid+1 , high, idx, value);
66
- }
52
+ void upgrade (NodeST<T> *prev, NodeST<T> *current, int low, int high,
53
+ int idx, int value) {
54
+ if (idx > high || idx < low || low > high)
55
+ return ;
56
+ if (low == high)
57
+ return current->data .apply (low, value);
58
+ int mid = low + (high - low) / 2 ;
59
+ if (idx <= mid) {
60
+ current->right = prev->right ;
61
+ current->left = new NodeST<T>(prev->left ->data );
62
+ upgrade (prev->left , current->left , low, mid, idx, value);
63
+ } else {
64
+ current->left = prev->left ;
65
+ current->right = new NodeST<T>(prev->right ->data );
66
+ upgrade (prev->right , current->right , mid + 1 , high, idx, value);
67
+ }
67
68
pull (current);
68
69
}
69
- Data<T> query (NodeST<T>* node, int low, int high, int left, int right) {
70
- if (left > high || right < low || low > high) return Data<T>{};
71
- if (left <= low && high <= right) return node->data ;
72
- int mid = low + (high - low)/2 ;
73
- Data<T> p1 = query (node->left , low, mid, left, right);
74
- Data<T> p2 = query (node->right , mid+1 , high, left, right);
75
- return unite (p1, p2);
70
+ Data<T> query (NodeST<T> *node, int low, int high, int left, int right) {
71
+ if (left > high || right < low || low > high)
72
+ return Data<T>{};
73
+ if (left <= low && high <= right)
74
+ return node->data ;
75
+ int mid = low + (high - low) / 2 ;
76
+ Data<T> p1 = query (node->left , low, mid, left, right);
77
+ Data<T> p2 = query (node->right , mid + 1 , high, left, right);
78
+ return unite (p1, p2);
76
79
}
77
80
78
81
int sz;
79
82
vector<NodeST<T> *> version;
80
-
83
+
81
84
PersistentSegmentTree (const vector<T> &v) {
82
- sz = (int ) v.size ();
85
+ sz = (int )v.size ();
83
86
version.push_back (new NodeST<T>());
84
- build (version.back (), v, 0 , sz - 1 );
87
+ build (version.back (), v, 0 , sz - 1 );
85
88
}
86
89
void modify (int from, int to, int idx, T value) {
87
- int n = (int ) version.size ();
90
+ int n = (int )version.size ();
88
91
assert (0 <= from && from < n && 0 <= to && to < n);
89
- upgrade (version[from], version[to], 0 , sz- 1 , idx, value);
92
+ upgrade (version[from], version[to], 0 , sz - 1 , idx, value);
90
93
}
91
94
int modify (int from, int idx, T value) {
92
- int n = (int ) version.size ();
95
+ int n = (int )version.size ();
93
96
assert (0 <= from && from < n);
94
97
version.push_back (new NodeST<T>());
95
- upgrade (version[from], version.back (), 0 , sz- 1 , idx, value);
96
- return (int ) version.size () - 1 ;
98
+ upgrade (version[from], version.back (), 0 , sz - 1 , idx, value);
99
+ return (int )version.size () - 1 ;
97
100
}
98
101
Data<T> query (int from, int low, int high) {
99
- int n = (int ) version.size ();
102
+ int n = (int )version.size ();
100
103
assert (0 <= from && from < n);
101
104
assert (0 <= low && low < sz && 0 <= high && high < sz && low <= high);
102
- return query (version[from], 0 , sz- 1 , low, high);
105
+ return query (version[from], 0 , sz - 1 , low, high);
103
106
}
104
107
};
105
108
106
- template <typename T>
107
- using persist_segtree = PersistentSegmentTree<T>;
109
+ template <typename T> using persist_segtree = PersistentSegmentTree<T>;
0 commit comments