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 }

 

 

 

你可能感兴趣的:(poj)