【二维RMQ】hdu 2888 Check Corners

来源:互联网 发布:上实剑桥 知乎 编辑:程序博客网 时间:2024/05/01 07:01

http://acm.hdu.edu.cn/showproblem.php?pid=2888

二维RMQ,支持静态查询区间最值(最小或最大)

/*  hdu 2888 二维RMQ  二维RMQ,支持静态查询,预处理O(n*m*lgn*lgm)  下标从1开始  注意与二维线段树的区别(支持动态更新)*/#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<vector>#include<set>#include<map>#include<algorithm>#include<sstream>#define eps 1e-9#define pi acos(-1)#define INF 0x7fffffff#define inf -INF#define MM 10#define N 1010using namespace std;typedef long long ll;const int _max = 300 + 10;int val[310][310];int dp[310][310][9][9];int mm[310];int n,m,Q;void initRMQ(int n,int m){  for(int i = 1; i <= n; ++ i)    for(int j = 1;j <= m;++j)    dp[i][j][0][0]=val[i][j];  for(int ii = 0; ii <= mm[n];++ ii)    for(int jj = 0; jj <= mm[m]; ++ jj)    if(ii+jj)    for(int i =1;i + (1<<ii)-1<=n; ++ i)     for(int j = 1;j+(1<<jj)-1<=m;++j){     if(ii)dp[i][j][ii][jj]=max(dp[i][j][ii-1][jj],dp[i+(1<<(ii-1))][j][ii-1][jj]);       else dp[i][j][ii][jj]=max(dp[i][j][ii][jj-1],dp[i][j+(1<<(jj-1))][ii][jj-1]);    }}//rmq查询(x1<=x2,y1<=y2)int rmq(int x1,int y1,int x2,int y2){  int k1= mm[x2-x1+1];  int k2 = mm[y2-y1+1];  x2=x2-(1<<k1)+1;  y2=y2-(1<<k2)+1;  return max(max(dp[x1][y1][k1][k2],dp[x1][y2][k1][k2]),max(dp[x2][y1][k1][k2],dp[x2][y2][k1][k2]));}int main(){   #ifndef ONLINE_JUDGE   freopen("input.txt","r",stdin);   #endif // ONLINE_JUDGE   //mm数组初始化   mm[0]=-1;   for(int i = 1; i <= 810; ++ i)    mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];   while(scanf("%d%d",&n,&m)==2){    for(int i = 1; i <= n; ++ i)        for(int j = 1;j <= m; ++ j)        scanf("%d",&val[i][j]);    int r1,c1,r2,c2,maxx;    initRMQ(n,m);    scanf("%d",&Q);    while(Q--){      scanf("%d%d%d%d",&r1,&c1,&r2,&c2);      if(r1>r2)swap(r1,r2);      if(c1>c2)swap(c1,c2);      maxx = rmq(r1,c1,r2,c2);      printf("%d ",maxx);      bool ok = (maxx==val[r1][c1])||(maxx==val[r1][c2])||(maxx==val[r2][c1])||(maxx==val[r2][c2]);      puts(ok?"yes":"no");    }   }   return 0;}


0 0
原创粉丝点击