P2216 [HAOI2007]理想的正方形
由于是二维区间查询,就用了二维st表
原理也很简单,懂得st表就可以看懂
不懂st表的可以参考ST表 RMQ ST表模板
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 5;
int a, b, n;
int v, k, l;
int st_min[maxn][maxn][11], st_max[maxn][maxn][11];
void init(){
for(int i = 1; (1 << i) <= n; i++){
for(int x = 1; x + (1 << i) - 1<= a; x++){
for(int y = 1; y + (1 << i) - 1 <= b; y++){
st_min[x][y][i] = min( min(st_min[x][y][i - 1], st_min[x + (1 << (i - 1))][y][i - 1]), min(st_min[x][y + (1 << (i - 1))][i - 1], st_min[x + (1 << (i - 1))][y + (1 << (i - 1))][ i -1]));
st_max[x][y][i] = max( max(st_max[x][y][i - 1], st_max[x + (1 << (i - 1))][y][i - 1]), max(st_max[x][y + (1 << (i - 1))][i - 1], st_max[x + (1 << (i - 1))][y + (1 << (i - 1))][ i -1]));
}
}
}
}
int RMQ(int x,int y,int xx,int yy)
{
int maxn = max( max(st_max[x][y][l], st_max[xx - (1 << l) + 1][y][l]), max(st_max[x][yy - (1 << l) + 1][l], st_max[xx - (1 << l) + 1][yy - (1 << l) + 1][l]));
int minn = min( min(st_min[x][y][l], st_min[xx - (1 << l) + 1][y][l]), min(st_min[x][yy - (1 << l) + 1][l], st_min[xx - (1 << l) + 1][yy - (1 << l) + 1][l]));
return maxn - minn;
}
int main(){
cin >> a >> b >> n;
for(int i = 1; i <= a; i++){
for(int j = 1; j <= b; j++){
cin >> v;
st_min[i][j][0] = v;
st_max[i][j][0] = v;
}
}
init();
while((1<<(l+1)) <= n) l++;
int ans = 1e9;
k = n;
for(int i = 1; i + n - 1 <= a; i++){
for(int j = 1; j + n - 1 <= b; j++){
ans = min(RMQ(i,j,i+k-1,j+k-1), ans);
}
}
cout << ans << endl;
return 0;
}