Cod sursa(job #1810952)

Utilizator Burbon13Burbon13 Burbon13 Data 20 noiembrie 2016 18:24:50
Problema Struti Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <cstdio>
#include <deque>

using namespace std;

const int nmx = 1002;

int n,m,p,mn,total;
int mat[nmx][nmx];
deque <int> dq[2][nmx], minim, maxim; /// 0 = minim, 1 = maxim

void citire()
{
    scanf("%d %d %d", &n, &m, &p);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            scanf("%d", &mat[i][j]);
}

void reset_deque(int x, int y)
{
    for(int i = 1; i <= n; ++i)
        for(int j = 0; j <= 1; ++j)
            dq[j][i].clear();
}

void adauga_coloana(int i, int j, int y)
{
    if(not dq[0][i].empty() && dq[0][i].back() <= j - y)
        dq[0][i].pop_back();
    while(not dq[0][i].empty() && mat[i][dq[0][i].front()] > mat[i][j])
        dq[0][i].pop_front();
    dq[0][i].push_front(j);

    if(not dq[1][i].empty() && dq[1][i].back() <= j - y)
        dq[1][i].pop_back();
    while(not dq[1][i].empty() && mat[i][dq[1][i].front()] < mat[i][j])
        dq[1][i].pop_front();
    dq[1][i].push_front(j);
}

void adauga_interval(int i, int x)
{
    if(not minim.empty() && minim.back() <= i - x)
        minim.pop_back();
    while(not minim.empty() && mat[minim.front()][dq[0][minim.front()].back()] > mat[i][dq[0][i].back()])
        minim.pop_front();
    minim.push_front(i);

    if(not maxim.empty() && maxim.back() <= i - x)
        maxim.pop_back();
    while(not maxim.empty() && mat[maxim.front()][dq[1][maxim.front()].back()] < mat[i][dq[1][i].back()])
        maxim.pop_front();
    maxim.push_front(i);
}

void calcul(int x, int y)
{
    reset_deque(x,y);

    for(int j = 1; j <= m; ++j)
    {
        for(int i = 1; i <= n; ++i)
            adauga_coloana(i,j,y);

        minim.clear();
        maxim.clear();

        if(j >= y)
            for(int i = 1; i <= n; ++i)
            {
                adauga_interval(i,x);

                if(i >= x)
                {
                    int diferenta = mat[maxim.back()][dq[1][maxim.back()].back()] - mat[minim.back()][dq[0][minim.back()].back()];

                    if(diferenta == mn)
                        ++ total;
                    else if(diferenta < mn)
                    {
                        mn = diferenta;
                        total = 1;
                    }
                }
            }
    }
}

int main()
{
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);
    citire();
    while(p--)
    {
        int x,y;
        scanf("%d %d", &x, &y);

        total = 0;
        mn = 1000000;

        calcul(x,y);

        if(x != y)
            calcul(y,x);

        printf("%d %d\n", mn, total);
    }
    return 0;
}