POJ 2019 二维RMQ

题意:

给出一个N*N的矩阵,要查询任意B*B子矩阵内的元素最大值和最小值之差。

 

思路:

没神马思路可言。刚刚做完一道RMQ,正好碰到这道题。。果断二维RMQ。

不要听到“二维”就想到二维线段树,应该想到二维树状数组(指变成复杂度)

二维RMQ 和就是在一维的基础上及一层循环

详见代码~

 

View Code
 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 }

 

 

 

posted @ 2012-10-05 08:35  proverbs  阅读(956)  评论(0编辑  收藏  举报