poj--2019 Cornfields 2维RMQ
题目大意: 给定一个 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; }
                    
                

                
            
        
浙公网安备 33010602011771号