-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSparseTable.h
More file actions
48 lines (40 loc) · 1.21 KB
/
SparseTable.h
File metadata and controls
48 lines (40 loc) · 1.21 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
#pragma once
#include <vector>
#include <algorithm>
#include <functional>
template<typename T>
class SparseTable {
private:
int n;
std::vector<int> logs;
// st[i][j] stores the range query result of [i, i + 2^j[
std::vector<std::vector<T>> st;
std::function<T(T, T)> f;
public:
SparseTable(const std::vector<T>& a,
std::function<T(T, T)> f = [](T a, T b) { return std::min(a, b); })
: n(int(a.size())), logs(n + 1), f{ f } {
logs[0] = -1;
for (int k = 1; k <= n; ++k)
logs[k] = logs[k >> 1] + 1;
int maxLog = logs[n];
st.assign(maxLog + 1, std::vector<T>(a.size()));
for (int i = 0; i < n; ++i)
st[0][i] = a[i];
// The range [i, i + 2^d[ splits in [i, i + 2^(d - 1)[ and [i + 2^(d - 1), i + 2^d[
for (int d = 1; d <= maxLog; ++d) {
// i + 2^d - 1 (last index of the sequence) must always be valid
for (int i = 0; i + (1 << d) - 1 < n; ++i)
st[d][i] = f(st[d - 1][i], st[d - 1][i + (1 << (d - 1))]);
}
}
T query(int l, int r) {
int d = logs[r - l + 1];
return f(st[d][l], st[d][r - (1 << d) + 1]);
}
void update(int k, T v) {
for (int d = 0; d <= logs[n]; ++d)
for (int i = max(0, k - (1 << d) + 1); i < min(n - (1 << d) + 1, k + 1); ++i)
st[d][i] = f(st[d][i], v);
}
};