-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathsegtree_.cpp
117 lines (105 loc) · 2.91 KB
/
segtree_.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
106
107
108
109
110
111
112
113
114
115
116
117
namespace segtree_ns {
struct item {
template<typename T>
void init(const T &t, int l, int r) {
}
void update(const item &first, const item &second, int l, int r) {
}
static item merge(const item &first, const item &second, int l, int r) {
item res;
res.update(first, second, l, r); // careful with different lengths
return res;
}
};
OSTREAM(item);
struct segtree {
vector<item> tree;
int n = 1;
segtree(int n = 1) : n(n) {
tree.resize(1 << (__lg(max(1, n - 1)) + 2));
}
template<typename T>
segtree(const vector<T>& v) {
build(v);
}
template<typename T>
void build(const vector<T> &v, int i, int l, int r) {
if (l == r) {
tree[i].init(v[l], l, r);
return;
}
int m = (l + r) >> 1;
build(v, i * 2 + 1, l, m);
build(v, i * 2 + 2, m + 1, r);
tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], l, r);
}
template<typename T>
void build(const vector<T> &v) {
n = v.size();
tree.assign(1 << (__lg(max(1, n - 1)) + 2), item());
build(v, 0, 0, n - 1);
}
item ask(int l, int r, int i, int vl, int vr) {
if (l == vl && r == vr) {
return tree[i];
}
int m = (vl + vr) >> 1;
if (r <= m) {
return ask(l, r, i * 2 + 1, vl, m);
} else if (m < l) {
return ask(l, r, i * 2 + 2, m + 1, vr);
} else {
return item::merge(ask(l, m, i * 2 + 1, vl, m), ask(m + 1, r, i * 2 + 2, m + 1, vr), l, r);
}
}
item ask(int l, int r) {
l = max(l, 0); r = min(r, n - 1);
if (l > r) return item();
return ask(l, r, 0, 0, n - 1);
}
template<typename T>
void set(int ind, const T &t) {
static array<pair<int, int>, 30> st;
int l = 0, r = n - 1, i = 0;
int ptr = -1;
while (l != r) {
st[++ptr] = {l, r};
int m = (l + r) >> 1;
if (ind <= m) {
i = i * 2 + 1;
r = m;
} else {
i = i * 2 + 2;
l = m + 1;
}
}
tree[i].init(t, l, r);
while (i != 0) {
i = (i - 1) / 2;
tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], st[ptr].first, st[ptr].second);
--ptr;
}
}
};
ostream& operator << (ostream& o, segtree& tree) {
#ifdef HOME
vector<item> items;
for (int i = 0; i < tree.n; ++i)
items.push_back(tree.ask(i, i));
const bool print_horizontal = true;
if (print_horizontal) {
for (int i = 0; i < items.size(); ++i) {
if (i != 0) o << " ";
o << items[i];
}
} else {
for (int i = 0; i < items.size(); ++i) {
o << '\n' << string(10, ' ');
o << items[i];
}
}
#endif
return o;
}
}
using namespace segtree_ns;