版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38013346/article/details/82120200
题意
题解
/*
* dp[i][j][k] 表示以 点(i,j)为左上顶点的长度为1<<k的正方形最大或最小值
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 300;
int maze[maxn][maxn],n;
struct ST {
int Max[maxn][maxn][10],Min[maxn][maxn][10];
int mm[maxn],kk[20];
void init() {
mm[0] = -1;
for(int i=0;i<n;i++) {
mm[i+1] = (((i+1) & i) == 0)? mm[i] + 1:mm[i];
for(int j=0;j<n;j++) {
Max[i][j][0] = Min[i][j][0] = maze[i][j];
}
}
// for(int i=0;i<=n;i++) printf("%d ",mm[i]);printf("\n");
kk[0] = 1;
for(int i=1;i<20;i++) kk[i] = kk[i-1]*2;
for(int k=1;kk[k]<=n;k++) {
for(int i=0;i+kk[k]-1<n;i++) {
for(int j=0;j+kk[k]-1<n;j++) {
Max[i][j][k] = max(max(Max[i][j][k-1],Max[i][j+kk[k-1]][k-1]),
max(Max[i+kk[k-1]][j][k-1],Max[i+kk[k-1]][j+kk[k-1]][k-1]));
Min[i][j][k] = min(min(Min[i][j][k-1],Min[i][j+kk[k-1]][k-1]),
min(Min[i+kk[k-1]][j][k-1],Min[i+kk[k-1]][j+kk[k-1]][k-1]));
}
}
}
}
int query(int x,int y,int l) {
int k = mm[l];
int maxa = max(max(Max[x][y][k],Max[x][y+l-kk[k]][k]),max(Max[x+l-kk[k]][y][k],Max[x+l-kk[k]][y+l-kk[k]][k]));
int mina = min(min(Min[x][y][k],Min[x][y+l-kk[k]][k]),min(Min[x+l-kk[k]][y][k],Min[x+l-kk[k]][y+l-kk[k]][k]));
// printf("%d %d %d\n",k,maxa,mina);
return maxa - mina;
}
}st;
int b,k;
int main()
{
while(~scanf("%d%d%d",&n,&b,&k)) {
for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&maze[i][j]);
st.init();
while(k--) {
int x,y;scanf("%d%d",&x,&y);
printf("%d\n",st.query(x-1,y-1,b));
}
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef short int sint;
const int maxn = 255;
int maze[maxn][maxn];
int n;
struct ST {
sint Min[maxn][maxn][8][8],Max[maxn][maxn][8][8];
sint mm[maxn],kk[8];
void init() {
mm[0] = -1;kk[0] = 1;
for(int i=0;i<n;i++) {
mm[i+1] = (((i+1) & i) == 0) ? mm[i] + 1: mm[i];
kk[i+1] = kk[i] * 2;
for(int j=0;j<n;j++) {
Min[i][j][0][0] = Max[i][j][0][0] = maze[i][j];
}
}
for(int k=0;kk[k]<=n;k++) {
for(int d=0;kk[d]<=n;d++) if(k+d){
for(int i=0;i+kk[k]-1<n;i++) {
for(int j=0;j+kk[k]-1<n;j++) {
if(k) {
Max[i][j][k][d] = max(Max[i][j][k-1][d],Max[i+kk[k-1]][j][k-1][d]);
Min[i][j][k][d] = min(Min[i][j][k-1][d],Min[i+kk[k-1]][j][k-1][d]);
}
else {
Max[i][j][k][d] = max(Max[i][j][k][d-1],Max[i][j+kk[d-1]][k][d-1]);
Min[i][j][k][d] = min(Min[i][j][k][d-1],Min[i][j+kk[d-1]][k][d-1]);
}
}
}
}
}
}
sint max_query(int x1,int y1,int x2,int y2) {
sint k1 = mm[x2-x1+1],k2 = mm[y2-y1+1];
x2 = x2 - kk[k1] + 1;
y2 = y2 - kk[k2] + 1;
return max(max(Max[x1][y1][k1][k2],Max[x1][y2][k1][k2]),max(Max[x2][y1][k1][k2],Max[x2][y2][k1][k2]));
}
sint min_query(int x1,int y1,int x2,int y2) {
sint k1 = mm[x2-x1+1],k2 = mm[y2-y1+1];
x2 = x2 - kk[k1] + 1;
y2 = y2 - kk[k2] + 1;
return min(min(Min[x1][y1][k1][k2],Min[x1][y2][k1][k2]),min(Min[x2][y1][k1][k2],Min[x2][y2][k1][k2]));
}
}st;
int b,k;
int main()
{
while(~scanf("%d%d%d",&n,&b,&k)) {
for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&maze[i][j]);
st.init();
while(k--) {
int x,y;scanf("%d%d",&x,&y);
x--;y--;
printf("%d\n",st.max_query(x,y,x+b-1,y+b-1)-st.min_query(x,y,x+b-1,y+b-1));
}
}
return 0;
}