[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 }

 

posted @ 2017-09-03 02:59  Elpsywk  阅读(279)  评论(0编辑  收藏  举报