poj 2019 二维rmq *

题目大意:给出一个N*N矩形,每个格子上有一个价值。询问一个b*b的矩形在左上角的位置(x,y),(x+b-1,y+b-1)这一部分的最大值-最小值是多少。

模板题

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <iostream>

 4 #include <algorithm>

 5 using namespace std;

 6 

 7 int val[255][255];

 8 int mm[255];

 9 int dpmin[255][255][8][8];//最小值

10 int dpmax[255][255][8][8];//最大值

11 

12 void initRMQ(int n,int m)

13 {

14     for(int i = 1;i <= n;i++)

15         for(int j = 1;j <= m;j++)

16             dpmin[i][j][0][0] = dpmax[i][j][0][0] = val[i][j];

17     for(int ii = 0; ii <= mm[n]; ii++)

18         for(int jj = 0; jj <= mm[m]; jj++)

19             if(ii+jj)

20                 for(int i = 1; i + (1<<ii) - 1 <= n; i++)

21                     for(int j = 1; j + (1<<jj) - 1 <= m; j++)

22                     {

23                         if(ii)

24                         {

25                             dpmin[i][j][ii][jj] = min(dpmin[i][j][ii-1][jj],dpmin[i+(1<<(ii-1))][j][ii-1][jj]);

26                             dpmax[i][j][ii][jj] = max(dpmax[i][j][ii-1][jj],dpmax[i+(1<<(ii-1))][j][ii-1][jj]);

27                         }

28                         else

29                         {

30                             dpmin[i][j][ii][jj] = min(dpmin[i][j][ii][jj-1],dpmin[i][j+(1<<(jj-1))][ii][jj-1]);

31                             dpmax[i][j][ii][jj] = max(dpmax[i][j][ii][jj-1],dpmax[i][j+(1<<(jj-1))][ii][jj-1]);

32                         }

33                     }

34 }

35 //查询矩形的最大值

36 int rmq1(int x1,int y1,int x2,int y2)

37 {

38     int k1 = mm[x2-x1+1];

39     int k2 = mm[y2-y1+1];

40     x2 = x2 - (1<<k1) + 1;

41     y2 = y2 - (1<<k2) + 1;

42     return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2]));

43 }

44 //查询矩形的最小值

45 int rmq2(int x1,int y1,int x2,int y2)

46 {

47     int k1 = mm[x2-x1+1];

48     int k2 = mm[y2-y1+1];

49     x2 = x2 - (1<<k1) + 1;

50     y2 = y2 - (1<<k2) + 1;

51     return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));

52 }

53 

54 

55 int main()

56 {

57     mm[0] = -1;

58     for(int i = 1;i <= 500;i++)

59         mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1];

60     int N,B,K;

61     while(scanf("%d%d%d",&N,&B,&K)==3)

62     {

63         for(int i = 1;i <= N;i++)

64             for(int j = 1;j <= N;j++)

65                 scanf("%d",&val[i][j]);

66         initRMQ(N,N);

67         int x,y;

68         while(K--)

69         {

70             scanf("%d%d",&x,&y);

71             printf("%d\n",rmq1(x,y,x+B-1,y+B-1)-rmq2(x,y,x+B-1,y+B-1));

72         }

73     }

74     return 0;

75 }
2015/7/4

 

你可能感兴趣的:(poj)