题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2888
之前可能学了假的二维RMQ,跑了9000多ms。。。。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=320; 7 int p[maxn][maxn]; 8 int pmax[maxn][maxn][20]; 9 int n,m,k; 10 11 void RMQ_INIT() 12 { 13 int f=log(n+0.0)/log(2.0); 14 for(int i=1;i<=n;i++) 15 for(int j=1;j<=m;j++) 16 pmax[i][j][0]=p[i][j]; 17 for(int i=1;i<=n;i++) 18 for(int k=1;k<=f;k++) 19 for(int j=1;j+(1<<k)-1<=m;j++) 20 { 21 pmax[i][j][k]=max(pmax[i][j][k-1],pmax[i][j+(1<<k-1)][k-1]); 22 } 23 return; 24 } 25 26 27 int rmq(int r1,int c1,int r2,int c2 ) 28 { 29 int l=c1,r=c2; 30 int k=log(r+0.0-l+1)/log(2.0); 31 int maxx=-0x3f3f3f3f; 32 for(int i=r1;i<=r2;i++) 33 { 34 maxx=max(maxx,max(pmax[i][l][k],pmax[i][r-(1<<k)+1][k])); 35 } 36 return maxx; 37 } 38 int main() 39 { 40 while(scanf("%d%d",&n,&m)!=EOF) 41 { 42 for(int i=1;i<=n;i++) 43 for(int j=1;j<=m;j++) 44 scanf("%d",&p[i][j]); 45 RMQ_INIT(); 46 int r1,r2,c1,c2; 47 scanf("%d",&k); 48 while(k--) 49 { 50 scanf("%d%d%d%d",&r1,&c1,&r2,&c2); 51 int x=rmq(r1,c1,r2,c2); 52 printf("%d ",x); 53 if(p[r1][c1]==x||p[r1][c2]==x||p[r2][c2]==x||p[r2][c1]==x) 54 puts("yes"); 55 else puts("no"); 56 } 57 } 58 59 }
二维RMQ
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=320; 7 int p[maxn][maxn]; 8 int pmax[maxn][maxn][9][9]; //不要盲目开大 9 int n,m,k; 10 11 void RMQ_INIT() 12 { 13 for(int i=1;i<=n;i++) 14 for(int j=1;j<=m;j++) 15 pmax[i][j][0][0]=p[i][j]; 16 for(int ii=0;(1<<ii)<=n;ii++) 17 for(int jj=0;(1<<jj)<=m;jj++) 18 if(ii+jj) 19 for(int i=1;i+(1<<ii)-1<=n;i++) 20 for(int j=1;j+(1<<jj)-1<=m;j++) 21 if(ii) pmax[i][j][ii][jj]=max(pmax[i][j][ii-1][jj],pmax[i+(1<<ii-1)][j][ii-1][jj]); 22 else pmax[i][j][ii][jj]=max(pmax[i][j][ii][jj-1],pmax[i][j+(1<<jj-1)][ii][jj-1]); 23 return ; 24 } 25 26 27 int rmq(int r1,int c1,int r2,int c2 ) 28 { 29 int k1=0,k2=0; 30 while((1<<k1+1)<=r2-r1+1) k1++; 31 while((1<<k2+1)<=c2-c1+1) k2++; 32 r2=r2-(1<<k1)+1; 33 c2=c2-(1<<k2)+1; 34 return max(max(pmax[r1][c1][k1][k2],pmax[r1][c2][k1][k2]),max(pmax[r2][c1][k1][k2],pmax[r2][c2][k1][k2])); 35 } 36 int main() 37 { 38 while(scanf("%d%d",&n,&m)!=EOF) 39 { 40 for(int i=1;i<=n;i++) 41 for(int j=1;j<=m;j++) 42 scanf("%d",&p[i][j]); 43 RMQ_INIT(); 44 int r1,r2,c1,c2; 45 scanf("%d",&k); 46 while(k--) 47 { 48 scanf("%d%d%d%d",&r1,&c1,&r2,&c2); 49 int x=rmq(r1,c1,r2,c2); 50 printf("%d ",x); 51 if(p[r1][c1]==x||p[r1][c2]==x||p[r2][c2]==x||p[r2][c1]==x) puts("yes"); 52 else puts("no"); 53 } 54 } 55 }