【BZOJ 1047】[HAOI2007]理想的正方形
【链接】 我是链接,点我呀:)
【题意】
【题解】
二维的ST表。 每个大的正方形可以由4个小的正方形组成。 然后区域内的最大值最小值。也可以由4个小的张方形部分全部覆盖到。【代码】
#include <bits/stdc++.h>
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define all(x) x.begin(),x.end()
#define pb push_back
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1
using namespace std;
const double pi = acos(-1);
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
const int N = 1000;
const int M = 10;
int a,b,n;
int ma[N+10][N+10][M+2],mi[N+10][N+10][M+2];
int get_max(int a,int b,int c,int d){
return max(a,max(b,max(c,d)));
}
int get_min(int a,int b,int c,int d){
return min(a,min(b,min(c,d)));
}
int main(){
#ifdef LOCAL_DEFINE
freopen("rush_in.txt", "r", stdin);
#endif
scanf("%d%d%d",&a,&b,&n);
rep1(i,1,a)
rep1(j,1,b){
scanf("%d",&ma[i][j][0]);
mi[i][j][0] = ma[i][j][0];
}
rep1(k,1,M){
int len = 1<<k;
rep1(i,1,a-len+1)
rep1(j,1,b-len+1){
ma[i][j][k] = get_max(ma[i][j][k-1],ma[i][j+len/2][k-1],ma[i+len/2][j][k-1],ma[i+len/2][j+len/2][k-1]);
mi[i][j][k] = get_min(mi[i][j][k-1],mi[i][j+len/2][k-1],mi[i+len/2][j][k-1],mi[i+len/2][j+len/2][k-1]);
}
}
int need = log2(n);
int ans = -1;
rep1(i,1,a-n+1)
rep1(j,1,b-n+1){
int temp1 = ma[i][j][need],temp2 = ma[i][j+n-(1<<need)][need];
int temp3 = ma[i+n-(1<<need)][j][need],temp4 = ma[i+n-(1<<need)][j+n-(1<<need)][need];
temp1 = get_max(temp1,temp2,temp3,temp4);
int tmp1 = mi[i][j][need],tmp2 = mi[i][j+n-(1<<need)][need];
int tmp3 = mi[i+n-(1<<need)][j][need],tmp4 = mi[i+n-(1<<need)][j+n-(1<<need)][need];
tmp1 = get_min(tmp1,tmp2,tmp3,tmp4);
if (ans==-1){
ans = temp1-tmp1;
}else{
ans = min(ans,temp1-tmp1);
}
}
cout<<ans<<endl;
return 0;
}