题目大意: 给定一个 N*N 的数组 求以(x1, y1) 为左上角 (x1 + b -1 ,y1 + b -1)为右下角 这个b*b的范围内最大值减最小值
看到最大值最小值当然想到RMQ啦
View Code
//Accepted 27392K 594MS C++ 2416B #include <iostream> #include <stdio.h> #include <cmath> using namespace std; const int maxn = 301; int N; int val[maxn][maxn]; int st_min[maxn][maxn][9][9]; int st_max[maxn][maxn][9][9]; inline int minn(int a,int b){ return a>b?b:a; } inline int maxx(int a,int b){ return a>b?a:b; } void RMQ_2D_PRE() {for(int row = 1; row <= N; row++)for(int col = 1; col<=N; col++){st_min[row][col][0][0] = val[row][col];st_max[row][col][0][0] = val[row][col];}int m = log(double(N)) / log(2.0);for(int i=0; i<=m; i++)for(int j=0; j<=m; j++){if(i == 0 && j==0)continue;for(int row = 1; row+(1<<i)-1 <= N; row++)for(int col = 1; col+(1<<j)-1 <= N; col++){if(i == 0){st_min[row][col][i][j] = minn(st_min[row][col][i][j-1] , st_min[row][col+(1<<(j-1))][i][j-1]); //水平划分st_max[row][col][i][j] = maxx(st_max[row][col][i][j-1] , st_max[row][col+(1<<(j-1))][i][j-1]); //水平划分 }else{st_min[row][col][i][j] = minn(st_min[row][col][i-1][j] , st_min[row+(1<<(i-1))][col][i-1][j]); //竖直划分st_max[row][col][i][j] = maxx(st_max[row][col][i-1][j] , st_max[row+(1<<(i-1))][col][i-1][j]); //竖直划分 }}} } int RMQ_2D_min(int x1,int x2,int y1,int y2) {int kx = log(double(x2 - x1 +1)) / log(2.0);int ky = log(double(y2 - y1 +1)) / log(2.0);int m1 = st_min[x1][y1][kx][ky];int m2 = st_min[x2-(1<<kx)+1][y1][kx][ky];int m3 = st_min[x1][y2-(1<<ky)+1][kx][ky];int m4 = st_min[x2-(1<<kx)+1][y2-(1<<ky)+1][kx][ky];return minn( minn(m1,m2), minn(m3,m4) );} int RMQ_2D_max(int x1,int x2,int y1,int y2) {int kx = log(double(x2 - x1 +1)) / log(2.0);int ky = log(double(y2 - y1 +1)) / log(2.0);int m1 = st_max[x1][y1][kx][ky];int m2 = st_max[x2-(1<<kx)+1][y1][kx][ky];int m3 = st_max[x1][y2-(1<<ky)+1][kx][ky];int m4 = st_max[x2-(1<<kx)+1][y2-(1<<ky)+1][kx][ky];return maxx( maxx(m1,m2), maxx(m3,m4) );} int main(void) {int M,B;int x1,y1;while(scanf("%d%d%d",&N,&B,&M)!=EOF){ for(int i=1; i<=N; i++)for(int j=1; j<=N; j++)scanf("%d",&val[i][j]); RMQ_2D_PRE(); while(M--){scanf("%d%d",&x1,&y1); printf("%d\n",RMQ_2D_max(x1,x1+B-1,y1,y1+B-1)-RMQ_2D_min(x1,x1+B-1,y1,y1+B-1));}}return 0; }