先逐行求出范围为B的最大最小值,再将每行范围B看成一列的一个数求出该列的最大最小值
#include <stdio.h>
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
int N, S, Q;
int m[250][250];
int M[250][250];
int main()
{
int i, j, k, r, c;
int *a, *b;
/* input */
scanf("%d%d%d", &N, &S, &Q);
for(i = 0; i < N; ++i){
for(j = 0; j < N; ++j){
scanf("%d", &m[i][j]);
M[i][j] = m[i][j];
}
}
/* preprocess */
if(S > 1){
/* RMQ each row with range S */
for(r = 0; r < N; ++r){
a = m[r];
b = M[r];
for(j = 0; (k = 1 << (j+1)) < S; ++j){
for(i = 0; i + k <= N; ++i){
a[i] = min(a[i], a[i + (1 << j)]);
b[i] = max(b[i], b[i + (1 << j)]);
}
}
k = S - (1 << j);
for(i = 0; i + S <= N; ++i){
a[i] = min(a[i], a[i + k]);
b[i] = max(b[i], b[i + k]);
}
}
/* RMQ cols with range S */
for(c = 0; c + S <= N; ++c){
for(j = 0; (k = 1 << (j+1)) < S; ++j){
for(i = 0; i + k <= N; ++i){
m[i][c] = min(m[i][c], m[i + (1 << j)][c]);
M[i][c] = max(M[i][c], M[i + (1 << j)][c]);
}
}
k = S - (1 << j);
for(i = 0; i + S <= N; ++i){
m[i][c] = min(m[i][c], m[i + k][c]);
M[i][c] = max(M[i][c], M[i + k][c]);
}
}
}
/* queries */
while(Q--){
scanf("%d%d", &r, &c);
printf("%d\n", M[r-1][c-1] - m[r-1][c-1]);
}
return 0;
}