标签:
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:y; } void Make_Rmq(int n,int m) { for(int i=0;(1<<i)<=n;++i) for(int j=0;(1<<j)<=m;++j) if(i!=0||j!=0) { for(int R=1;R+(1<<i)-1<=n;++R) for(int C=1;C+(1<<j)-1<=m;++C) { if(!i)dp[R][C][i][j]=mmax(dp[R][C][i][j-1],dp[R][C+(1<<j-1)][i][j-1]); else dp[R][C][i][j]=mmax(dp[R][C][i-1][j],dp[R+(1<<i-1)][C][i-1][j]); } } } int Get_Rmq(int x1,int y1,int x2,int y2) { int k1=0,k2=0; while((1<<k1+1)<=x2-x1+1) k1++; while((1<<k2+1)<=y2-y1+1) k2++; return mmax(mmax(dp[x1][y1][k1][k2],dp[x2-(1<<k1)+1][y1][k1][k2]),mmax(dp[x1][y2-(1<<k2)+1][k1][k2],dp[x2-(1<<k1)+1][y2-(1<<k2)+1][k1][k2])); } void solve() { int n,m,Q,x1,x2,y2,y1; while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&dp[i][j][0][0]); scanf("%d",&Q); Make_Rmq(n,m); while(Q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int res1=Get_Rmq(x1,y1,x2,y2); bool res2=false; if(res1==dp[x1][y1][0][0]||res1==dp[x1][y2][0][0]||res1==dp[x2][y1][0][0]||res1==dp[x2][y2][0][0])res2=true; printf("%d ",res1); printf(res2?"yes\n":"no\n"); } } } int main() { solve(); return 0; }
标签:
原文地址:http://www.cnblogs.com/kiuhghcsc/p/5740762.html