题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2888
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 305;
int a[N][N]; // 原数组
int f[N][N][9][9]; // 记录最大值
int query(int x1, int y1, int x2, int y2)
{
int k1 = log(x2 - x1 + 1) / log(2);
int k2 = log(y2 - y1 + 1) / log(2);
int tmp1 = max(f[x1][y1][k1][k2], f[x1][y2 - (1 << k2) + 1][k1][k2]);
int tmp2 = max(f[x2 - (1 << k1) + 1][y1][k1][k2], f[x2 - (1 << k1) + 1][y2 - (1 << k2) + 1][k1][k2]);
return max(tmp1, tmp2);
}
int main()
{
// n行m列
int n, m;
while (~scanf("%d%d", &n, &m))
{
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 ii = 0; (1 << ii) <= n; ii++)
{
for (int jj = 0; (1 << jj) <= m; jj++)
{
if (ii == 0 && jj == 0) continue;
for (int i = 1; i + (1 << ii) - 1 <= n; i++)
{
for (int j = 1; j + (1 << jj) - 1 <= m; j++)
{
if (ii)
{
f[i][j][ii][jj] = max(f[i][j][ii - 1][jj], f[i + (1 << ii - 1)][j][ii - 1][jj]);
}
else
{
f[i][j][ii][jj] = max(f[i][j][ii][jj - 1], f[i][j + (1 << jj - 1)][ii][jj - 1]);
}
}
}
}
}
// q次查询
int q;
scanf("%d", &q);
while (q--)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
int maxx = query(x1, y1, x2, y2);
if (a[x1][y1] == maxx || a[x1][y2] == maxx || a[x2][y1] == maxx || a[x2][y2] == maxx)
{
printf("%d yes\n", maxx);
}
else
{
printf("%d no\n", maxx);
}
}
}
return 0;
}