HDU2888 Check Corners

Description

Paul draw a big m*n matrix A last month, whose entries Ai,j are all integer numbers ( 1 <= i <= m, 1 <= j <= n ). Now he selects some sub-matrices, hoping to find the maximum number. Then he finds that there may be more than one maximum number, he also wants to know the number of them. But soon he find that it is too complex, so he changes his mind, he just want to know whether there is a maximum at the four corners of the sub-matrix, he calls this “Check corners”. It’s a boring job when selecting too many sub-matrices, so he asks you for help. (For the “Check corners” part: If the sub-matrix has only one row or column just check the two endpoints. If the sub-matrix has only one entry just output “yes”.)

Input

There are multiple test cases.

For each test case, the first line contains two integers m, n (1 <= m, n <= 300), which is the size of the row and column of the matrix, respectively. The next m lines with n integers each gives the elements of the matrix which fit in non-negative 32-bit integer.

The next line contains a single integer Q (1 <= Q <= 1,000,000), the number of queries. The next Q lines give one query on each line, with four integers r1, c1, r2, c2 (1 <= r1 <= r2 <= m, 1 <= c1 <= c2 <= n), which are the indices of the upper-left corner and lower-right corner of the sub-matrix in question.

Output

For each test case, print Q lines with two numbers on each line, the required maximum integer and the result of the “Check corners” using “yes” or “no”. Separate the two parts with a single space.

Sample Input

4 4
4 4 10 7
2 13 9 11
5 7 8 20
13 20 8 2
4
1 1 4 4
1 1 3 3
1 3 3 4
1 1 1 1

Sample Output

20 no
13 no
20 yes
4 yes

Source

2009 Multi-University Training Contest 9 - Host by HIT

二维RMQ练习题。

一维RMQ二分维护一个区间,而二维RMQ通过维护四个等分的矩形区间维护了一个区间的最值,基本原理差不多

理解的还不是很透彻,代码基本靠抄。

这题内存限制范围很小,数组稍微开大就MLE

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 int f[302][302][9][9];
 9 //f[i][j][x][y]记录以(i,j)为左上角,(i+(1<<x),j+(1<<y))为右下角的矩形内的最大值
10 int mp[302][302];
11 int n,m;
12 void init(){
13     int i,j;
14     int k,l;
15     for(i=1;i<=n;i++)
16       for(j=1;j<=m;j++)
17           f[i][j][0][0]=mp[i][j];
18     int kn=(int)(log((double)n)/log(2.0));
19     int km=(int)(log((double)m)/log(2.0));
20     for(i=0;i<=kn;i++)
21       for(j=0;j<=km;j++){
22           if(i==0 && j==0)continue;
23           for(k=1;k+(1<<i)-1<=n;k++)
24               for(l=1;l+(1<<j)-1<=m;l++){
25                   if(!i)//i==0 && j!=0
26                       f[k][l][i][j]=max(f[k][l][i][j-1],f[k][l+(1<<(j-1))][i][j-1]);
27                   else //i!=0
28                       f[k][l][i][j]=max(f[k][l][i-1][j],f[k+(1<<(i-1))][l][i-1][j]);
29               }
30         }
31     return;
32 }
33 int RMQ(int x1,int y1,int x2,int y2){
34     int kn=(int)(log(double(x2-x1+1))/log(2.0));
35     int km=(int)(log(double(y2-y1+1))/log(2.0));
36     int a=max(f[x1][y1][kn][km],f[x2-(1<<kn)+1][y1][kn][km]);
37     int b=max(f[x1][y2-(1<<km)+1][kn][km],f[x2-(1<<kn)+1][y2-(1<<km)+1][kn][km]);
38     return max(a,b);
39 }
40 int main(){
41     int i,j;
42     int k;
43     while(scanf("%d%d",&n,&m)!=-1){
44
45         for(i=1;i<=n;i++)
46           for(j=1;j<=m;j++)
47               scanf("%d",&mp[i][j]);
48         init();
49         int x1,x2,y1,y2;
50         scanf("%d",&k);
51         while(k--){
52             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
53             int ans=RMQ(x1,y1,x2,y2);
54             printf("%d ",ans);
55             if(ans==mp[x1][y1] || ans==mp[x2][y2] || ans==mp[x1][y2] || ans==mp[x2][y1])
56                 puts("yes");
57             else puts("no");
58         }
59     }
60     return 0;
61 }
时间: 2024-10-25 12:08:00

HDU2888 Check Corners的相关文章

HDU2888 Check Corners(二维RMQ)

有一个矩阵,每次查询一个子矩阵,判断这个子矩阵的最大值是不是在这个子矩阵的四个角上 裸的二维RMQ 1 #pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8

hdu 2888 Check Corners(RMQ)

题目链接:hdu 2888 Check Corners 题目大意:给定一个矩阵,每次查询矩阵中的最大值,并且判断该最大值是否在所查询的角落上. 解题思路:一开始用线段树,一维RMQ都超时了,然后换成了二维的RMQ,结果MLE,dp数组换成9?9就过了. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 305; int N, M,

HDU 2888:Check Corners 二维RMQ

Check Corners 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2888 题意: 求矩形区间内的最大值 题解: 二维RMQ,和一维的区别不大,按一维的做法求出每一行上的RMQ,再处理行与行之间的关系就好了. 代码 #include<stdio.h> const int N=301; const int M=301; int dp[N][M][9][9]; int mmax(int x,int y) { return x>y?x:

【HDOJ 2888】Check Corners(裸二维RMQ)

Problem Description Paul draw a big m*n matrix A last month, whose entries Ai,j are all integer numbers ( 1 <= i <= m, 1 <= j <= n ). Now he selects some sub-matrices, hoping to find the maximum number. Then he finds that there may be more tha

HDU 2888:Check Corners(二维RMQ)

http://acm.hdu.edu.cn/showproblem.php?pid=2888 题意:给出一个n*m的矩阵,还有q个询问,对于每个询问有一对(x1,y1)和(x2,y2),求这个子矩阵中的最大值,和判断四个角有没有等于这个最大值的. 思路:二维RMQ模板题.注意内存卡的挺紧的. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5

hdu 2888 Check Corners

/* 题意:给出m,n代表给出长为m宽为n的矩阵,然后给出一个q代表查询的次数,然后q行每行给出一个 r1, c1, r2, c2 且满足(1 <= r1 <= r2 <= m, 1 <= c1 <= c2 <= n) 输出这个矩形范围内的最大值,如果最大值是四个顶点某一个的话就输出yes否则输出no */ #include<stdio.h> #include<math.h> #define Max(a,b) a>b?a:b int dp[

Check Corners HDU - 2888(二维RMQ)

就是板题.. 查询子矩阵中最大的元素...然后看看是不是四个角落的  是就是yes  不是就是no  判断一下就好了 #include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #includ

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基