HDU2888 二维RMQ

#include<iostream>
#include
<math.h>
using namespace std;
const int MAX=320;
int a[MAX][MAX];
int dp[MAX][MAX][10][10];
int n,m;
int rmq()
{
    
for(int i=1;i<=n;++i)
        
for(int j=1;j<=m;++j)
            dp[i][j][
0][0]=a[i][j];
    
for(int i=0;(1<<i)<=n;++i)
    {
        
int di=1<<i;
        
for(int j=0;(1<<j)<=m;++j)
        {
            
if(i==0&&j==0)
                
continue;
            
int dj=1<<j;
            
for(int ii=1;ii+di-1<=n;++ii)
                
for(int jj=1;jj+dj-1<=m;++jj)
                {
                    
if(i==0)
                        dp[ii][jj][i][j]
=max(dp[ii][jj][i][j-1],dp[ii][jj+(1<<(j-1))][i][j-1]);
                    
else
                        dp[ii][jj][i][j]
=max(dp[ii][jj][i-1][j],dp[ii+(1<<(i-1))][jj][i-1][j]);
                }
        }
    }
    
return 0;
}
int query(int l1,int l2,int r1,int r2)
{
    
if(l1>l2)swap(l1,l2);
    
if(r1>r2)swap(r1,r2);
    
int kn=(int)(log(l2-l1+1.0)/log(2.0));
    
int km=(int)(log(r2-r1+1.0)/log(2.0));
    
int v1=dp[l1][r1][kn][km];
    
int v2=dp[l1][r2-(1<<km)+1][kn][km];
    
int v3=dp[l2-(1<<kn)+1][r1][kn][km];
    
int v4=dp[l2-(1<<kn)+1][r2-(1<<km)+1][kn][km];
    
return max(max(v1,v2),max(v3,v4));
}

int main()
{
    
while(scanf("%d%d",&n,&m)!=EOF)
    {
        
for(int i=1;i<=n;++i)
            
for(int j=1;j<=m;++j)
                scanf(
"%d",&a[i][j]);
        rmq();
        
int q;
        scanf(
"%d",&q);
        
while(q--)
        {
            
int r1,c1,r2,c2;
            scanf(
"%d%d%d%d",&r1,&c1,&r2,&c2);
            
int k=query(r1,r2,c1,c2);
            printf(
"%d ",k);
            
if(k==a[r1][c1]||k==a[r1][c2]||k==a[r2][c1]||k==a[r2][c2])
                printf(
"yes\n");
            
else
                printf(
"no\n");
        }
    }
}
posted @ 2009-08-12 01:06  unber  阅读(427)  评论(0)    收藏  举报