-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsparse_table.cpp
More file actions
36 lines (31 loc) · 1.22 KB
/
sparse_table.cpp
File metadata and controls
36 lines (31 loc) · 1.22 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
class SparseTable {
private:
vector<int> msb_; // 1 << msb[i] = most significant bit of i
vector<vector<int>> arr_;
public:
explicit SparseTable(size_t n) {
msb_ = vector<int>(n + 1);
msb_[0] = -1;
for (int i = 1; i <= n; i++)
msb_[i] = ((i & (i - 1)) == 0) + msb_[i - 1];
arr_ = vector<vector<int>>(n, vector<int>(msb_[n] + 1, 0));
}
explicit SparseTable(const vector<int>& arr) {
*this = SparseTable(arr.size());
for (int i = 0; i < arr_.size(); i++)
Append(i, arr[i]);
}
static inline int op(int a, int b) noexcept { return min(a, b); }
[[nodiscard]] int Query(size_t l, size_t r) const { //0-indexed, works properly if only append was called
return op(arr_[r][msb_[r - l + 1]],
arr_[(1 << msb_[r - l + 1]) + l - 1][msb_[r - l + 1]]);
}
void Append(int pos, int element) {
//arr[pos] = element; query(l, r) works properly if there were append(pos + 1, a), ..., append(r, z)
arr_[pos][0] = element;
for (int i = 1; i <= msb_[pos + 1]; i++) {
int previous = pos - (1 << (i - 1));
arr_[pos][i] = op(arr_[pos][i - 1], arr_[previous][i - 1]);
}
}
};