-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsegmentTree.cpp
More file actions
155 lines (138 loc) · 3.95 KB
/
segmentTree.cpp
File metadata and controls
155 lines (138 loc) · 3.95 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 遅延評価つきセグメント木
// update: [l, r) の区間を v に変更
// query: [l, r) の区間の和を求める
struct ST {
vector<ll> seg, lazy;
int size;
ST(int n) {
size = 1;
while (size < n) size *= 2;
seg.resize(size * 2);
lazy.resize(size * 2, -1);
}
void push(int k, int l, int r) {
if (lazy[k] != -1) {
seg[k] = lazy[k] * (r - l);
if (r - l > 1) {
lazy[k * 2 + 1] = lazy[k];
lazy[k * 2 + 2] = lazy[k];
}
lazy[k] = -1;
}
}
ll merge(ll x, ll y) {
return x + y;
}
void update(int a, int b, ll v, int k, int l, int r) {
push(k, l, r);
if (r <= a || b <= l) return;
if (a <= l && r <= b) {
lazy[k] = v;
push(k, l, r);
} else {
update(a, b, v, k * 2 + 1, l, (l + r) / 2);
update(a, b, v, k * 2 + 2, (l + r) / 2, r);
seg[k] = merge(seg[k * 2 + 1], seg[k * 2 + 2]);
}
}
void update(int a, int b, ll v) {
return update(a, b, v, 0, 0, size);
}
ll query(int a, int b, int k, int l, int r) {
push(k, l, r);
if (r <= a || b <= l) return 0;
if (a <= l && r <= b) return seg[k];
ll x = query(a, b, k * 2 + 1, l, (l + r) / 2);
ll y = query(a, b, k * 2 + 2, (l + r) / 2, r);
return merge(x, y);
}
ll query(int a, int b) {
return query(a, b, 0, 0, size);
}
};
// 遅延評価つきセグメント木
// update: [l, r) の区間に値 v を一様に追加する
// query: [l, r) の区間の和を求める
struct ST {
vector<ll> seg, lazy;
int size;
ST(int n) {
size = 1;
while (size < n) size *= 2;
seg.resize(size * 2);
lazy.resize(size * 2);
}
inline void push(int k, int l, int r) {
if (lazy[k] != 0) {
seg[k] += lazy[k] * (r - l);
if (r - l > 1) {
lazy[k * 2 + 1] += lazy[k];
lazy[k * 2 + 2] += lazy[k];
}
lazy[k] = 0;
}
}
inline ll merge(ll x, ll y) {
return x + y;
}
void update(int a, int b, ll v, int k, int l, int r) {
push(k, l, r);
if (r <= a || b <= l) return;
if (a <= l && r <= b) {
lazy[k] += v;
push(k, l, r);
} else {
update(a, b, v, k * 2 + 1, l, (l + r) / 2);
update(a, b, v, k * 2 + 2, (l + r) / 2, r);
seg[k] = merge(seg[k * 2 + 1], seg[k * 2 + 2]);
}
}
void update(int a, int b, ll v) {
return update(a, b, v, 0, 0, size);
}
ll query(int a, int b, int k, int l, int r) {
push(k, l, r);
if (r <= a || b <= l) return 0;
if (a <= l && r <= b) return seg[k];
ll x = query(a, b, k * 2 + 1, l, (l + r) / 2);
ll y = query(a, b, k * 2 + 2, (l + r) / 2, r);
return merge(x, y);
}
ll query(int a, int b) {
return query(a, b, 0, 0, size);
}
};
// セグメント木(RMQ 対応)
// update: k 番目の値を a に変更
// query: [l, r) の区間の最大値を求める
template<typename T>
struct ST {
vector<T> seg;
int size;
ST(int n) {
size = 1;
while (size < n) size *= 2;
seg.resize(2*size-1, numeric_limits<T>::min());
}
inline T merge(T x, T y) {
return max(x, y);
}
void update(int k, T a) {
k += size-1;
seg[k] = a;
while (k > 0) {
k = (k-1)/2;
seg[k] = merge(seg[k*2+1], seg[k*2+2]);
}
}
T query(int a, int b, int k, int l, int r) {
if (r <= a || b <= l) return numeric_limits<T>::min();
if (a <= l && r <= b) return seg[k];
T vl = query(a, b, k*2+1, l, (l+r)/2);
T vr = query(a, b, k*2+2, (l+r)/2, r);
return merge(vl, vr);
}
T query(int a, int b) {
return query(a, b, 0, 0, size);
}
};