# luogu P2216 [HAOI2007]理想的正方形

$stmax_{i,j,k}$表示以$i$$j$为右下角端点边长为$2^k$的正方形内最大值为多少。

$max(stmax_{i,j-q+2^k,k},max(stmax_{i,j,k},max(stmax_{i-q+2^k,j,k},stmax_{i-q+2^k,j-q+2^k,k}$

$min(stmin_{i,j-q+2^k,k},min(stmin_{i,j,k},min(stmin_{i-q+2^k,j,k},stmin_{i-q+2^k,j-q+2^k,k}$

#include<cstdio>
using namespace std;
int n,m,q,stmin[1039][1039][10],stmax[1039][1039][10],ans=1e9,tot,pus,a[1039][1039];
inline int max(int a,int b) {
return a>b?a:b;
}
inline int min(int a,int b) {
return a<b?a:b;
}
char s=getchar();x=0;
while(s<'0'||s>'9') s=getchar();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+(s^48),s=getchar();
}
int main() {
register int i,j,k;
scanf("%d%d%d",&n,&m,&q);
for(i=1; i<=n; i++) {
}
for(k=1; (1<<k)<=q; k++) {
for(i=1<<k; i<=n; i++) {
for(j=1<<k; j<=m; j++) {
stmax[i][j][k]=max(stmax[i][j-(1<<k-1)][k-1],max(stmax[i][j][k-1],max(stmax[i-(1<<k-1)][j][k-1],stmax[i-(1<<k-1)][j-(1<<k-1)][k-1])));
stmin[i][j][k]=min(stmin[i][j-(1<<k-1)][k-1],min(stmin[i][j][k-1],min(stmin[i-(1<<k-1)][j][k-1],stmin[i-(1<<k-1)][j-(1<<k-1)][k-1])));
}
}
}
k=0;
while((1<<k+1)<=q) k++;
for(i=q; i<=n; i++) {
for(j=q; j<=m; j++) {
ans=min(ans,max(stmax[i][j-q+(1<<k)][k],max(stmax[i][j][k],max(stmax[i-q+(1<<k)][j][k],stmax[i-q+(1<<k)][j-q+(1<<k)][k])))-min(stmin[i][j-q+(1<<k)][k],min(stmin[i][j][k],min(stmin[i-q+(1<<k)][j][k],stmin[i-q+(1<<k)][j-q+(1<<k)][k]))));
}
}
printf("%d",ans);
return 0;
}


©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客