标签:
题意:N,B,K表示原矩阵为N*N,查询矩阵为B*B,K次查询;
每次查询给出a,b,表示矩阵左上方的坐标为(a,b);求查询矩阵中最大值与最小值之差;
思路:二维RMQ,将dp的一三维看做第一维,二四维看做第二维;注意细节;
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int N,B,K; int dpmax[255][255][8][8]; int dpmin[255][255][8][8]; int mm[255][255],num[255]; void init_rmq(int n,int m){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ dpmax[i][j][0][0]=mm[i][j]; dpmin[i][j][0][0]=mm[i][j]; } } for(int ii=0;ii<=num[n];ii++){ for(int jj=0;jj<=num[m];jj++){ if(ii+jj){ //细节 for(int i=1;i+(1<<ii)-1<=n;i++){ for(int j=1;j+(1<<jj)-1<=m;j++){ if(ii){ //细节 dpmax[i][j][ii][jj]=max(dpmax[i][j][ii-1][jj],dpmax[i+(1<<(ii-1))][j][ii-1][jj]); dpmin[i][j][ii][jj]=min(dpmin[i][j][ii-1][jj],dpmin[i+(1<<(ii-1))][j][ii-1][jj]); } else{ dpmax[i][j][ii][jj]=max(dpmax[i][j][ii][jj-1],dpmax[i][j+(1<<(jj-1))][ii][jj-1]); dpmin[i][j][ii][jj]=min(dpmin[i][j][ii][jj-1],dpmin[i][j+(1<<(jj-1))][ii][jj-1]); } } } } } } } int rmqmax(int x1,int y1,int x2,int y2){ int k1=num[x2-x1+1]; int k2=num[y2-y1+1]; x2=x2-(1<<k1)+1; y2=y2-(1<<k2)+1; return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2])); } int rmqmin(int x1,int y1,int x2,int y2){ int k1=num[x2-x1+1]; int k2=num[y2-y1+1]; x2=x2-(1<<k1)+1; y2=y2-(1<<k2)+1; return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2])); } int main(){ int i,j,k,a,b; num[0]=-1; for(i=1;i<=255;i++){ num[i]=(i&(i-1))==0?num[i-1]+1:num[i-1]; } while(scanf("%d%d%d",&N,&B,&K)!=EOF){ for(i=1;i<=N;i++){ for(j=1;j<=N;j++){ scanf("%d",&mm[i][j]); } } init_rmq(N,N); while(K--){ scanf("%d%d",&a,&b); int t1=rmqmax(a,b,a+B-1,b+B-1); int t2=rmqmin(a,b,a+B-1,b+B-1); printf("%d\n",t1-t2); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/dominatingdashuzhilin/p/4737511.html