poj 2019

来源:互联网 发布:菜鸟软件科技有限公司 编辑:程序博客网 时间:2024/04/28 21:16

题意简单,去子矩阵的最大值和最小值的差。


ST二维的不懂,用了暴力。时间差别不大。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>


using namespace std;


const int maxn = 255;
int n, b, k;
short dpmin[maxn][maxn][10][10];
short dpmax[maxn][maxn][10][10];
short val[maxn][maxn];


void init()
{
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            dpmin[i][j][0][0] = dpmax[i][j][0][0] = val[i][j]; 
    int k = (int)(log((double)n) / log(2.0));
    for (int i = 0; i <= k; ++i)
    {
        for (int j = 0; j <= k; ++j)
        {
            if (0 == i && 0 == j)
                continue;
            for (int r = 1; r + (1 << i) - 1 <= n; ++r)
            {
                for (int c = 1; c + (1 << j) - 1 <= n; ++c)
                {
                    if (0 == i)
                    {
                        dpmin[r][c][i][j] = min(dpmin[r][c][i][j-1], dpmin[r][c+(1<<(j-1))][i][j-1]);
                        dpmax[r][c][i][j] = max(dpmax[r][c][i][j-1], dpmax[r][c+(1<<(j-1))][i][j-1]);
                    }
                    else
                    {
                        dpmin[r][c][i][j] = min(dpmin[r][c][i-1][j], dpmin[r+(1<<(i-1))][c][i-1][j]);
                        dpmax[r][c][i][j] = max(dpmax[r][c][i-1][j], dpmax[r+(1<<(i-1))][c][i-1][j]);
                    }
                }
            }
        }
    }
}


short query(int r1, int c1, int r2, int c2)
{
    int kr = (int)(log((double)r2 - r1 + 1) / log(2.0));
    int kc = (int)(log((double)c2 - c1 + 1) / log(2.0));
    
    short t1 = dpmax[r1][c1][kr][kc];
    short t2 = dpmax[r2-(1<<kr)+1][c1][kr][kc];
    short t3 = dpmax[r1][c2-(1<<kc)+1][kr][kc];
    short t4 = dpmax[r2-(1<<kr)+1][c2-(1<<kc)+1][kr][kc];
    
    short m1 = dpmin[r1][c1][kr][kc];
    short m2 = dpmin[r2-(1<<kr)+1][c1][kr][kc];
    short m3 = dpmin[r1][c2-(1<<kc)+1][kr][kc];
    short m4 = dpmin[r2-(1<<kr)+1][c2-(1<<kc)+1][kr][kc];
    
    return max(max(t1, t2), max(t3, t4)) - min(min(m1, m2), min(m3, m4));
}


void read()
{
    scanf("%d %d %d", &n, &b, &k);
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
            scanf("%d", &val[i][j]);
    }
    init();
    int r1, c1, r2, c2;
    for (int i = 0; i < k; ++i)
    {
        scanf("%d %d", &r1, &c1);
        r2 = r1 + b - 1;
        c2 = c1 + b - 1;
        printf("%d\n", query(r1, c1, r2, c2));
    }
}


int main()
{
    read();
    return 0;
}




0 0