Maximum value of matrix
Topic link: ybt high-efficiency advanced 4-3-4
General idea
Give you a matrix, ask multiple times, ask the maximum value of a sub-matrix.
Ideas
This question can be seen using a two-dimensional ST table.
It's easy to think of, but the implementation can be said to be very disgusting.
The query is actually okay, the main reason is that the thinking of the merger must be clear.
And because you are a matrix, you have to merge the two cases of one line. (One horizontal line and one vertical line)
Because you are a matrix, if you don't deal with these two, the DP merge will not work normally after it.
You can look at the code for details.
Code
#include<cstdio>
#include<iostream>
using namespace std;
int n, m, k, a[251][251];
int f[251][251][11][11];
int log[251], x1, y1, x2, y2;
void get_log() {
//预处理 log
int now = 1, x = 0;
while ((now << 1) <= 250) {
for (int i = now; i < (now << 1); i++)
log[i] = x;
x++;
now <<= 1;
}
while (now <= 250) {
log[now++] = x;
}
}
int main() {
get_log();
scanf("%d %d %d", &n, &m, &k);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
f[i][j][0][0] = a[i][j];
}
for (int j = 1; j <= log[m]; j++)//处理横着一根线的
for (int ii = 1; ii <= n; ii++)
for (int jj = 1; jj <= m; jj++) {
f[ii][jj][0][j] = f[ii][jj][0][j - 1];
if (jj + (1 << (j - 1)) <= m) f[ii][jj][0][j] = max(f[ii][jj][0][j], f[ii][jj + (1 << (j - 1))][0][j - 1]);
}
for (int i = 1; i <= log[n]; i++)//处理竖着一根线的
for (int ii = 1; ii <= n; ii++)
for (int jj = 1; jj <= m; jj++) {
f[ii][jj][i][0] = f[ii][jj][i - 1][0];
if (ii + (1 << (i - 1)) <= n) f[ii][jj][i][0] = max(f[ii][jj][i][0], f[ii + (1 << (i - 1))][jj][i - 1][0]);
}
for (int i = 1; i <= log[n]; i++)//ST 表的合并(前面两个其实也是,但是是为了处理掉特殊情况)
for (int j = 1; j <= log[m]; j++)
for (int ii = 1; ii <= n; ii++)
for (int jj = 1; jj <= m; jj++) {
f[ii][jj][i][j] = f[ii][jj][i - 1][j - 1];
if (ii + (1 << (i - 1)) <= n) {
f[ii][jj][i][j] = max(f[ii][jj][i][j], f[ii + (1 << (i - 1))][jj][i - 1][j - 1]);
if (jj + (1 << (j - 1)) <= m) {
f[ii][jj][i][j] = max(f[ii][jj][i][j], max(f[ii][jj + (1 << (j - 1))][i - 1][j - 1], f[ii + (1 << (i - 1))][jj + (1 << (j - 1))][i - 1][j - 1]));
}
}
else if (jj + (1 << (j - 1)) <= m) f[ii][jj][i][j] = max(f[ii][jj][i][j], f[ii][jj + (1 << (j - 1))][i - 1][j - 1]);
}
while (k--) {
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
int logx = log[x2 - x1 + 1];
int logy = log[y2 - y1 + 1];//询问
printf("%d\n", max(max(f[x1][y1][logx][logy], f[x1][y2 - (1 << logy) + 1][logx][logy]), max(f[x2 - (1 << logx) + 1][y1][logx][logy], f[x2 - (1 << logx) + 1][y2 - (1 << logy) + 1][logx][logy])));
}
return 0;
}