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 }