【RMQ】Poj 2019 Cornfields (二维)

题意:
给出一个 N * N 的矩阵(行列的编号都是 1-n),有 q 组询问,每组询问包含 row,col ,代表从 row行 ,col列 开始的 b * b 大小的矩阵,使其 max-min 值最大

O(n * m * log(n) * log(m) - O(1) 方法

int t,n,m,l,r,q,b,x,y;

int a[maxn][maxn];
int maxs[maxn][maxn][8][8];
int mins[maxn][maxn][8][8];

void RMQ(){
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			maxs[i][j][0][0] = mins[i][j][0][0] = a[i][j];
	for(int k=0;(1<<k)<=n;k++){
		for(int t=0;(1<<t)<=n;t++){
			if(k+t){
				for(int i=1;i+(1<<k)-1<=n;i++){
					for(int j=1;j+(1<<t)-1<=n;j++){
						if(k){
							maxs[i][j][k][t]=max(maxs[i][j][k-1][t],maxs[i+(1<<(k-1))][j][k-1][t]);
							mins[i][j][k][t]=min(mins[i][j][k-1][t],mins[i+(1<<(k-1))][j][k-1][t]);
						}else{
							maxs[i][j][k][t]=max(maxs[i][j][k][t-1],maxs[i][j+(1<<(t-1))][k][t-1]);
							mins[i][j][k][t]=min(mins[i][j][k][t-1],mins[i][j+(1<<(t-1))][k][t-1]);
						}
					}
				}
			}
		}
	}
}
int querymax(int x1,int y1,int x2,int y2){
	int k=log(x2-x1+1)/log(2.0);
	int t=log(y2-y1+1)/log(2.0);
	x2 = x2-(1<<k)+1;
	y2 = y2-(1<<t)+1;
    return max(max(maxs[x1][y1][k][t],maxs[x1][y2][k][t]),max(maxs[x2][y1][k][t],maxs[x2][y2][k][t]));
}
int querymin(int x1,int y1,int x2,int y2){
	int k=log(x2-x1+1)/log(2.0);
	int t=log(y2-y1+1)/log(2.0);
	x2 = x2-(1<<k)+1;
	y2 = y2-(1<<t)+1;
    return min(min(mins[x1][y1][k][t],mins[x1][y2][k][t]),min(mins[x2][y1][k][t],mins[x2][y2][k][t]));
}
int main(){
	scanf("%d%d%d",&n,&b,&q);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				scanf("%d",&a[i][j]);
		RMQ();
		while(q--){
			scanf("%d%d",&x,&y);
			printf("%d\n",querymax(x,y,x+b-1,y+b-1)-querymin(x,y,x+b-1,y+b-1));
		}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值