求矩阵中,以给定点(i,j)为左上角的,大小为b * b的矩形内,最大值和最小值的差。
ST表
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 255;
int mmax[maxn][maxn][10],mmin[maxn][maxn][10];
int num[maxn][maxn];
int n,b,k,step = 0,tmp = 0;
void init()
{
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++) {
mmax[i][j][0] = mmin[i][j][0] = num[i][j];
}
}
int t1,t2;
for (int len = 1; (1 << len) <= n; len ++) {//这里递推顺序非常重要,必须先把len = 1的所有i,j都算出来,再计算len = 2...
for (int i = 1; i <= n && i - 1 + (1 << len) <= n; i ++) {
for (int j = 1; j <= n && j - 1 + (1 << len) <= n; j ++) {
tmp = 1 << (len - 1);
t1 = max(mmax[i][j][len - 1],mmax[i + tmp][j][len - 1]);
t2 = max(mmax[i][j + tmp][len - 1],mmax[i + tmp][j + tmp][len - 1]);
mmax[i][j][len] = max(t1,t2);
t1 = min(mmin[i][j][len - 1],mmin[i + tmp][j][len - 1]);
t2 = min(mmin[i][j + tmp][len - 1],mmin[i + tmp][j + tmp][len - 1]);
mmin[i][j][len] = min(t1,t2);
}
}
}
}
int querymax(int x,int y)
{
int t1 = max(mmax[x][y][step],mmax[x + b - tmp][y][step]);
int t2 = max(mmax[x][y + b - tmp][step],mmax[x + b - tmp][y + b - tmp][step]);
return max(t1,t2);
}
int querymin(int x,int y)
{
int t1 = min(mmin[x][y][step],mmin[x + b - tmp][y][step]);
int t2 = min(mmin[x][y + b - tmp][step],mmin[x + b - tmp][y + b - tmp][step]);
return min(t1,t2);
}
int main()
{
while (scanf("%d%d%d",&n,&b,&k) != EOF) {
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++) {
scanf("%d",&num[i][j]);
}
}
init();
step = 0;
while (1 << (1 + step) <= b) step ++;//
tmp = 1 << step ;
int x,y,ans1 = -maxn,ans2 = maxn;
for (int cn = 0; cn < k; cn ++) {
scanf("%d%d",&x,&y);
if(b == 1) printf("0\n");
else{
ans1 = querymax(x,y);
ans2 = querymin(x,y);
printf("%d\n",ans1 - ans2);
}
}
}
return 0;
}