1. 程式人生 > >poj2019 二維RMQ模板題

poj2019 二維RMQ模板題

和hdu2888基本上一樣的,也是求一個矩陣內的極值

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 252
int n,b,q;
int dpmax[maxn][maxn][9][9],dpmin[maxn][maxn][9][9],val[maxn][maxn];
void ST(){
    int k=log2(n);
    
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dpmax[i][j][0][0]=dpmin[i][j][0][0]=val[i][j]; for(int i=0;i<=k;i++)//先求出一行內的最大值和最小值,然後再求出行間的最大值和最小值 for(int j=0;j<=k;j++){ if(i==0 && j==0) continue; for(int r=1;r+(1<<i)-1<=n;r++)
for(int c=1;c+(1<<j)-1<=n;c++) if(i==0){//在同一行內 dpmax[r][c][i][j]=max(dpmax[r][c][i][j-1],dpmax[r][c+(1<<(j-1))][i][j-1]); dpmin[r][c][i][j]=min(dpmin[r][c][i][j-1],dpmin[r][c+(1<<(j-1))][i][j-1]); }
else { dpmax[r][c][i][j]=max(dpmax[r][c][i-1][j],dpmax[r+(1<<(i-1))][c][i-1][j]); dpmin[r][c][i][j]=min(dpmin[r][c][i-1][j],dpmin[r+(1<<(i-1))][c][i-1][j]); } } } int query(int r,int c){ int r1=r,c1=c,r2=r+b-1,c2=c+b-1,k=log2(b); int max1=dpmax[r1][c1][k][k]; int max2=dpmax[r2-(1<<k)+1][c1][k][k]; int max3=dpmax[r1][c2-(1<<k)+1][k][k]; int max4=dpmax[r2-(1<<k)+1][c2-(1<<k)+1][k][k]; int min1=dpmin[r1][c1][k][k]; int min2=dpmin[r2-(1<<k)+1][c1][k][k]; int min3=dpmin[r1][c2-(1<<k)+1][k][k]; int min4=dpmin[r2-(1<<k)+1][c2-(1<<k)+1][k][k]; return max(max(max1,max2),max(max3,max4))-min(min(min1,min2),min(min3,min4)); } int main(){ while(scanf("%d%d%d",&n,&b,&q)==3){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&val[i][j]); ST();int r,c; while(q--){ scanf("%d%d",&r,&c); printf("%d\n",query(r,c)); } } return 0; }