232's competitive-programming templates.
DisjointSparseTable
232-aka-pretty-pi
2024. 8. 3. 02:17
template <typename T, typename F>
struct DisjointSparseTable {
int n;
std::vector<std::vector<T>> mat;
F func;
DisjointSparseTable(const std::vector<T>& a, const F& f = F {}) : n(int(a.size())), func(f) {
mat.push_back(a);
for (int p = 1; (1 << p) < n; ++p) {
mat.emplace_back(n);
for (int mid = 1 << p; mid < n; mid += 1 << (p + 1)) {
mat[p][mid - 1] = a[mid - 1];
for (int j = mid - 2; j >= (mid ^ 1 << p); --j) {
mat[p][j] = func(a[j], mat[p][j + 1]);
}
mat[p][mid] = a[mid];
for (int j = mid + 1; j < std::min(n, mid + (1 << p)); ++j) {
mat[p][j] = func(mat[p][j - 1], a[j]);
}
}
}
}
[[nodiscard]] T get(int l, int r) const {
assert(0 <= l && l < r && r <= n);
if (r - l == 1) {
return mat[0][l];
}
int p = 31 ^ __builtin_clz(l ^ (r - 1));
return func(mat[p][l], mat[p][r - 1]);
}
};