本题碉堡了,内存限制好紧,再大一点都不行,还只能用int,开始用short WA了好多次。。。。。
题意:给一个矩阵,然后给Q个询问,每个询问有四个数,分别代表询问的子矩阵的左上角和右下角,然后找出子矩阵的最大值输出,然后再把这个值与
子矩阵的四个角的值比较,如果有至少一个等于这个最大值就输出“yes”,否则输出“no”。
#include <stdio.h>
#include <iostream>
#include <math.h>
using namespace std;
const int N = 302;
int n, m;
int val[N][N];
int dpmax[N][N][9][9];
void ST()
{
int i, j, r, c, k1, k2;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
dpmax[i][j][0][0]=val[i][j];
k1=(int)(log(double(n))/log(2.0));
k2=(int)(log(double(m))/log(2.0));
for(i=0;i<=k1;i++)
{
for(j=0;j<=k2;j++)
{
if(i==0&&j==0) continue;
for(r=1;r+(1<<i)-1<=n;r++)
{
for(c=1;c+(1<<j)-1<=m;c++)
{
if(i==0)
dpmax[r][c][i][j]=max(dpmax[r][c][i][j-1],dpmax[r][c+(1<<(j-1))][i][j-1]);
else
dpmax[r][c][i][j]=max(dpmax[r][c][i-1][j],dpmax[r+(1<<(i-1))][c][i-1][j]);
}
}
}
}
}
int query(int r1, int c1, int r2, int c2)
{
int kr=(int)(log(double(r2-r1+1))/log(2.0));
int kc=(int)(log(double(c2-c1+1))/log(2.0));
int t1=dpmax[r1][c1][kr][kc];
int t2=dpmax[r2-(1<<kr)+1][c1][kr][kc];
int t3=dpmax[r1][c2-(1<<kc)+1][kr][kc];
int t4=dpmax[r2-(1<<kr)+1][c2-(1<<kc)+1][kr][kc];
return max(max(t1,t2),max(t3,t4));
}
int main()
{
int i, j, k;
int r1,c1,r2,c2;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&val[i][j]);
ST();
scanf("%d",&k);
while(k--)
{
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
int ret=query(r1,c1,r2,c2);
printf("%d ",ret);
if(val[r1][c1]==ret||val[r1][c2]==ret||val[r2][c1]==ret||val[r2][c2]==ret) puts("yes");
else puts("no");
}
}
return 0;
}