-
Notifications
You must be signed in to change notification settings - Fork 5
/
segment_tree.cpp
105 lines (83 loc) · 2.2 KB
/
segment_tree.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <bits/stdc++.h>
template <typename T>
class SegTree {
using AssociativeFunc = std::function<T (T&,T&)>;
private:
static int left(int x) { return (x<<1) + 1; }
static int right(int x) { return (x<<1) + 2; }
static int mid(int l, int r) { return (r-l)/2 + l; }
int size; // width of the segment tree
T defValue; // default value used in the seg tree
AssociativeFunc f; // associative function that combines two segments
std::vector<T> st; // Stores the seg tree
void build(std::vector<T>& a, int x, int lx, int rx) {
if (rx-lx == 1) {
if (lx < a.size()) {
st[x] = a[lx];
}
return;
} else {
int mx = SegTree::mid(lx,rx);
build(a, SegTree::left(x), lx, mx);
build(a, SegTree::right(x), mx, rx);
st[x] = f(st[SegTree::left(x)], st[SegTree::right(x)]);
}
}
void set(int i, T v, int x, int lx, int rx) {
if (rx-lx == 1) {
st[x] = v;
return;
}
int mx = SegTree::mid(lx,rx);
if (i < mx) {
set(i, v, SegTree::left(x), lx, mx);
} else {
set(i, v, SegTree::right(x), mx, rx);
}
st[x] = f(st[SegTree::left(x)], st[SegTree::right(x)]);
}
T rangeQuery(int l, int r, int x, int lx, int rx) {
if (rx <= l || r <= lx) {
return defValue;
} else if (l <= lx && rx <= r) {
return st[x];
} else {
int mx = SegTree::mid(lx,rx);
T res1 = rangeQuery(l, r, SegTree::left(x), lx, mx);
T res2 = rangeQuery(l, r, SegTree::right(x), mx, rx);
return f(res1, res2);
}
}
void debugPrintElements(int x, int lx, int rx) {
if (rx-lx == 1) {
std::cout << st[x] << ',';
return;
}
int mx = SegTree::mid(lx, rx);
debugPrintElements(SegTree::left(x), lx, mx);
debugPrintElements(SegTree::right(x), mx, rx);
}
public:
SegTree(int numElements, T defaultValue, AssociativeFunc funct)
:defValue{defaultValue}, f{funct} {
size = 1;
while (size < numElements) { size = (size<<1); }
st.assign(size<<1, defaultValue);
}
void build(std::vector<T>& elements) {
build(elements, 0, 0, size);
}
void set(int i, T v) {
set(i, v, 0, 0, size);
}
T rangeQuery(int l, int r) {
return rangeQuery(l, r, 0, 0, size);
}
void debugPrintElements() {
debugPrintElements(0, 0, size);
std::cout << std::endl;
}
};
int main() {
return 0;
}