[poj2019]Cornfields(二维RMQ)
题意:给你一个n*n的矩阵,让你从中圈定一个小矩阵,其大小为b*b,有q个询问,每次询问告诉你小矩阵的左上角,求小矩阵内的最大值和最小值的差。
解题关键:二维st表模板题。
预处理复杂度:$O({n^2}\log n)$
查询复杂度:$O(n)$
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<cmath> 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 typedef long long ll; 10 int arr[252][252]; 11 int max1[255][255][10],min1[255][255][10]; 12 int n,b,k; 13 void rmq_init(int n){ 14 int lg=int(log(n)/log(2)); 15 for(int i=1;i<=n;i++){ 16 for(int j=1;j<=n;j++){ 17 max1[i][j][0]=min1[i][j][0]=arr[i][j]; 18 } 19 } 20 for(int i=1;i<=n;i++){ 21 for(int j=1;j<=lg;j++){ 22 for(int k=1;k<=n;k++){ 23 max1[i][k][j]=max(max1[i][k][j-1],max1[i][k+(1<<(j-1))][j-1]); 24 min1[i][k][j]=min(min1[i][k][j-1],min1[i][k+(1<<(j-1))][j-1]); 25 } 26 } 27 } 28 } 29 int query(int x,int y){ 30 int k=int(log(b)/log(2.0)); 31 int maxd=-inf,mind=inf,tmp1,tmp2,yr=y+b-1; 32 for(int i=x;i<=x+b-1;i++){ 33 tmp1=max(max1[i][y][k],max1[i][yr-(1<<k)+1][k]);//k询问时就不需要再减1了 34 tmp2=min(min1[i][y][k],min1[i][yr-(1<<k)+1][k]); 35 maxd=max(tmp1,maxd); 36 mind=min(tmp2,mind); 37 } 38 return maxd-mind; 39 } 40 int main(){ 41 ios::sync_with_stdio(0); 42 while(cin>>n>>b>>k){ 43 for(int i=1;i<=n;i++){ 44 for(int j=1;j<=n;j++){ 45 cin>>arr[i][j]; 46 } 47 } 48 rmq_init(n); 49 int a,b; 50 while(k--){ 51 cin>>a>>b; 52 int ans=query(a,b); 53 cout<<ans<<"\n"; 54 } 55 } 56 return 0; 57 }