BZOJ1047: [HAOI2007]理想的正方形
【传送门:BZOJ1047】
简要题意:
给出a,b,n,给出一个a*b的矩阵,要求在这个矩阵中得到一个n*n的矩阵,使得这个n*n的矩阵的最大值-最小值的差最小,求出最小的差
题解:
二维ST表(涨姿势)
mx[i][j][k]表示左上角为(i-2k+1,j-2k+1),右下角为(i,j)的矩阵的最大值,mn[i][j][k]为最小值
然后随便yy一下继承
然后O(1)求最大最小值
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int mx[1100][1100][11],mn[1100][1100][11]; int bin[11],Log[1100]; int main() { int a,b,n; scanf("%d%d%d",&a,&b,&n); Log[0]=-1;for(int i=1;i<=max(a,b);i++) Log[i]=Log[i/2]+1; bin[0]=1;for(int i=1;i<=10;i++) bin[i]=bin[i-1]<<1; memset(mx,0,sizeof(mx));memset(mn,63,sizeof(mn)); for(int i=1;i<=a;i++) for(int j=1;j<=b;j++) scanf("%d",&mx[i][j][0]),mn[i][j][0]=mx[i][j][0]; for(int i=1;i<=a;i++) { for(int j=1;j<=b;j++) { for(int k=1;bin[k]<=min(i,j);k++) { mx[i][j][k]=max(mx[i][j][k-1],max(mx[i-bin[k-1]][j][k-1],max(mx[i][j-bin[k-1]][k-1],mx[i-bin[k-1]][j-bin[k-1]][k-1]))); mn[i][j][k]=min(mn[i][j][k-1],min(mn[i-bin[k-1]][j][k-1],min(mn[i][j-bin[k-1]][k-1],mn[i-bin[k-1]][j-bin[k-1]][k-1]))); } } } int ans=1<<31-1; for(int i=n;i<=a;i++) { for(int j=n;j<=b;j++) { int x=i-n+1,y=j-n+1; int k=Log[n]; int mmax,mmin; mmax=max(mx[i][j][k],max(mx[x+bin[k]-1][j][k],max(mx[i][y+bin[k]-1][k],mx[x+bin[k]-1][y+bin[k]-1][k]))); mmin=min(mn[i][j][k],min(mn[x+bin[k]-1][j][k],min(mn[i][y+bin[k]-1][k],mn[x+bin[k]-1][y+bin[k]-1][k]))); ans=min(mmax-mmin,ans); } } printf("%d\n",ans); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚