POJ 2019 二维RMQ
题意:
给出一个N*N的矩阵,要查询任意B*B子矩阵内的元素最大值和最小值之差。
思路:
没神马思路可言。刚刚做完一道RMQ,正好碰到这道题。。果断二维RMQ。
不要听到“二维”就想到二维线段树,应该想到二维树状数组(指变成复杂度)
二维RMQ 和就是在一维的基础上及一层循环
详见代码~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <cstdlib> 5 #include <iostream> 6 #include <cmath> 7 8 #define N 500 9 10 using namespace std; 11 12 int pmax[N][N][11],pmin[N][N][10],a[N][N],n,q,d,maxans,minans; 13 14 void init_rmq() 15 { 16 for(int i=1;i<=n;i++) 17 for(int j=1;j<=n;j++) 18 pmax[i][j][0]=pmin[i][j][0]=a[i][j]; 19 20 for(int i=1;i<=n;i++) 21 for(int k=1;(1<<k)<=n;k++) 22 for(int j=1;j+(1<<k)-1<=n;j++) 23 { 24 pmax[i][j][k]=max(pmax[i][j][k-1],pmax[i][j+(1<<(k-1))][k-1]); 25 pmin[i][j][k]=min(pmin[i][j][k-1],pmin[i][j+(1<<(k-1))][k-1]); 26 } 27 } 28 29 void read() 30 { 31 for(int i=1;i<=n;i++) 32 for(int j=1;j<=n;j++) 33 scanf("%d",&a[i][j]); 34 init_rmq(); 35 } 36 37 void askrmq(int a,int b) 38 { 39 int k=(int)(log(double(d))/log(2.0)); 40 maxans=0; minans=0x3f3f3f3f; 41 int l=b,r=b+d-1; 42 for(int i=a;i<a+d;i++) 43 { 44 maxans=max(maxans,max(pmax[i][l][k],pmax[i][r-(1<<k)+1][k])); 45 minans=min(minans,min(pmin[i][l][k],pmin[i][r-(1<<k)+1][k])); 46 } 47 } 48 49 void go() 50 { 51 for(int i=1,a,b;i<=q;i++) 52 { 53 scanf("%d%d",&a,&b); 54 askrmq(a,b); 55 printf("%d\n",maxans-minans); 56 } 57 } 58 59 int main() 60 { 61 while(scanf("%d%d%d",&n,&d,&q)!=EOF) 62 { 63 read(); 64 go(); 65 } 66 return 0; 67 }
没有人能阻止我前进的步伐,除了我自己!