标签:
Description
Input
Output
Sample Input
Sample Output
Source
二维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 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5654753.html