Cod sursa(job #794529)

Utilizator SchumiDumitru Andrei Georgian Schumi Data 6 octombrie 2012 14:47:15
Problema Struti Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include <cassert>
#include <cstdio>

using namespace std;

const int N = 1005;
const int INF = 0x3f3f3f3f;

int n, m, q;
int sol, nrSol;
int mat[N][N], maxMat[N][N], minMat[N][N];
int deqMin[N], deqMax[N];

void solve(int x, int y) {
    int xmin, xmax, ymin, ymax;

    sol = INF;
    nrSol = 0;
    
    for (int i = 1; i <= n; ++i) {
        xmin = xmax = 1;
        ymin = ymax = 0;
        
        for (int j = 1; j <= m; ++j) {
            while (ymin >= xmin && mat[i][deqMin[ymin]] >= mat[i][j])
                --ymin;
            deqMin[++ymin] = j;
            while (deqMin[xmin] <= j - y)
                ++xmin;
            minMat[i][j] = mat[i][deqMin[xmin]];
           
            while (ymax >= xmax && mat[i][deqMax[ymax]] <= mat[i][j])
                --ymax;
            deqMax[++ymax] = j;
            while (deqMax[xmax] <= j - y)
                ++xmax;
            maxMat[i][j] = mat[i][deqMax[xmax]];
        }
    }
    
    for (int j = y; j <= m; ++j) {
        xmin = xmax = 1;
        ymin = ymax = 0;
        
        for (int i = 1; i <= n; ++i) {
            while (ymin >= xmin && minMat[deqMin[ymin]][j] >= minMat[i][j])
                --ymin;
            deqMin[++ymin] = i;
            while (deqMin[xmin] <= i - x)
                ++xmin;

            while (ymax >= xmax && maxMat[deqMax[ymax]][j] <= maxMat[i][j])
                --ymax;
            deqMax[++ymax] = i;
            while (deqMax[xmax] <= i - x)
                ++xmax;

            if (i < x)
                continue;

            int rez = maxMat[deqMax[xmax]][j] - minMat[deqMin[xmin]][j];
            if (rez < sol) {
                sol = rez;
                nrSol = 1;
            } else if (rez == sol)
                ++nrSol;

        }
    }
}

int main() {
    assert(freopen("struti.in", "r", stdin) != NULL);
    assert(freopen("struti.out", "w", stdout) != NULL);

    assert(scanf("%d %d %d", &n, &m, &q) == 3);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            assert(scanf("%d", &mat[i][j]) == 1);

    while (q--) {
        int x, y;
        assert(scanf("%d %d", &x, &y) == 2);
        
        solve(x, y);
        if (x != y)
            solve(y, x);
        
        printf("%d %d\n", sol, nrSol);
    }
}