二维RMQ--poj2019 cornfield

求矩阵中,以给定点(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;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值