-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSegmentTreeIterative.cpp
60 lines (46 loc) · 1.6 KB
/
SegmentTreeIterative.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
template<typename T>
struct segment_tree {
int n;
vector<T> tree;
T identity_element;
function<T(const T&, const T&)> merge;
segment_tree(int _n, T _identity_element, const function<T(const T&, const T&)> &_merge) {
init(_n, _identity_element, _merge);
}
void init(int _n, T _identity_element, const function<T(const T&, const T&)> &_merge) {
n = _n;
identity_element = _identity_element;
merge = _merge;
tree.assign(2 * n, identity_element);
}
void build(const vector<T> &a) {
for (int i = 0; i < n; i++)
tree[i + n] = a[i];
for (int i = n - 1; i > 0; i--)
tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
}
void identity_modify(int pos, T val) {
pos += n;
for (tree[pos] = merge(tree[pos], val); pos >>= 1; )
tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]);
}
void increment(int pos, T val) {
pos += n;
for (tree[pos] += val; pos >>= 1; )
tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]);
}
void set(int pos, T val) {
pos += n;
for (tree[pos] = val; pos >>= 1; )
tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]);
}
T query(int l, int r) {
T res = identity_element;
for (l += n, r += n; l <= r; l >>= 1, r >>= 1) {
if (l & 1) res = merge(res, tree[l++]);
if (!(r & 1)) res = merge(res, tree[r--]);
}
return res;
}
T query(int pos) { return query(pos, pos); }
};