Cod sursa(job #2809418)

Utilizator IvanAndreiIvan Andrei IvanAndrei Data 26 noiembrie 2021 22:58:28
Problema Struti Scor 80
Compilator cpp-64 Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 3.05 kb
#include <fstream>
#include <deque>

using namespace std;

ifstream in ("struti.in");
ofstream out ("struti.out");

const int max_size = 1e3 + 1, INF = 1e4;

int a[max_size][max_size], maxi[max_size][max_size], mini[max_size][max_size], n, m;

void coloana_minim (int j, int dy)
{
    deque <int> dq;
    for (int i = 1; i <= n; i++)
    {
        if (!dq.empty () && dq.front () == i - dy)
        {
            dq.pop_front ();
        }
        while (!dq.empty () && a[dq.back ()][j] >= a[i][j])
        {
            dq.pop_back ();
        }
        dq.push_back (i);
        mini[i][j] = a[dq.front ()][j];
    }
}

void coloana_maxim (int j, int dy)
{
    deque <int> dq;
    for (int i = 1; i <= n; i++)
    {
        if (!dq.empty () && dq.front () == i - dy)
        {
            dq.pop_front ();
        }
        while (!dq.empty () && a[dq.back ()][j] <= a[i][j])
        {
            dq.pop_back ();
        }
        dq.push_back (i);
        maxi[i][j] = a[dq.front ()][j];
    }
}

void calcul_minime (int dy)
{
    for (int i = 1; i <= m; i++)
    {
        coloana_minim (i, dy);
    }
}

void calcul_maxime (int dy)
{
    for (int i = 1; i <= m; i++)
    {
        coloana_maxim (i, dy);
    }
}

void diferenta_min (int dx, int dy, int &difmin, int &nr)
{
    calcul_minime (dy);
    calcul_maxime (dy);
    deque <int> minime, maxime;
    for (int i = dy; i <= n; i++)
    {
        minime.clear ();
        maxime.clear ();
        for (int j = 1; j <= m; j++)
        {
            if (!minime.empty () && minime.front () == j - dx)
            {
                minime.pop_front ();
            }
            while (!minime.empty () && mini[i][minime.back ()] >= mini[i][j])
            {
                minime.pop_back ();
            }
            if (!maxime.empty () && maxime.front () == j - dx)
            {
                maxime.pop_front ();
            }
            while (!maxime.empty () && maxi[i][maxime.back ()] <= maxi[i][j])
            {
                maxime.pop_back ();
            }
            minime.push_back (j);
            maxime.push_back (j);
            if (j < dx)
                continue;
            int rez = maxi[i][maxime.front ()] - mini[i][minime.front ()];
            if (rez < difmin)
            {
                nr = 0;
                difmin = rez;
            }
            if (rez == difmin)
            {
                nr++;
            }
        }
    }
}

void solve (int dx, int dy)
{
    int difmin = INF, nr = 0;
    diferenta_min (dx, dy, difmin, nr);
    if (dx != dy)
    {
        diferenta_min (dy, dx, difmin, nr);
    }
    out << difmin << " " << nr <<'\n';
}

int main ()
{
    int k;
    in >> n >> m >> k;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m;j++)
        {
            in >> a[i][j];
        }
    }
    while (k--)
    {
        int dx, dy;
        in >> dx >> dy;
        solve (dx, dy);
    }
    in.close ();
    out.close ();
    return 0;
}