Spase
unknown
c_cpp
4 years ago
1.5 kB
7
Indexable
template <class T, class Compare = less<T>>
struct SparseTable2d {
int n = 0, m = 0;
T**** table;
int* log;
inline T choose(T x, T y) {
return Compare()(x, y) ? x : y;
}
SparseTable2d(vector<vector<T>>& grid) {
if(grid.empty() || grid[0].empty()) return;
n = grid.size(); m = grid[0].size();
log = new int[max(n, m) + 1];
log[1] = 0;
for(int i = 2; i <= max(n, m); i++)
log[i] = log[i - 1] + ((i ^ (i - 1)) > i);
table = new T***[n];
for(int i = n - 1; i >= 0; i--) {
table[i] = new T**[m];
for(int j = m - 1; j >= 0; j--) {
table[i][j] = new T*[log[n - i] + 1];
for(int k = 0; k <= log[n - i]; k++) {
table[i][j][k] = new T[log[m - j] + 1];
if(!k) table[i][j][k][0] = grid[i][j];
else table[i][j][k][0] = choose(table[i][j][k-1][0], table[i+(1<<(k-1))][j][k-1][0]);
for(int l = 1; l <= log[m - j]; l++)
table[i][j][k][l] = choose(table[i][j][k][l-1], table[i][j+(1<<(l-1))][k][l-1]);
}
}
}
}
T query(int r1, int r2, int c1, int c2) {
assert(r1 >= 0 && r2 < n && r1 <= r2);
assert(c1 >= 0 && c2 < m && c1 <= c2);
int rl = log[r2 - r1 + 1], cl = log[c2 - c1 + 1];
T ca1 = choose(table[r1][c1][rl][cl], table[r2-(1<<rl)+1][c1][rl][cl]);
T ca2 = choose(table[r1][c2-(1<<cl)+1][rl][cl], table[r2-(1<<rl)+1][c2-(1<<cl)+1][rl][cl]);
return choose(ca1, ca2);
}
};
Editor is loading...