Spase
unknown
c_cpp
3 years ago
1.5 kB
1
Indexable
Never
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); } };