Cod sursa(job #3211692)

Utilizator profinfo114Prof Info profinfo114 Data 9 martie 2024 23:57:04
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <fstream>

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, dq[max_size], minime[max_size], maxime[max_size];

void coloana_minim (int j, int dy)
{
    int st = 1, dr = 0;
    //deque <int> dq;
    for (int i = 1; i <= n; i++)
    {
        if (st <= dr && dq[st] == i - dy)
        {
            st++;
        }
        while (st <= dr && a[dq[dr]][j] >= a[i][j])
        {
            dr--;
        }
        dq[++dr] = i;;
        mini[i][j] = a[dq[st]][j];
    }
}

void coloana_maxim (int j, int dy)
{
    int st = 1, dr = 0;
    //deque <int> dq;
    for (int i = 1; i <= n; i++)
    {
        if (st <= dr && dq[st] == i - dy)
        {
            st++;
        }
        while (st <= dr && a[dq[dr]][j] <= a[i][j])
        {
            dr--;
        }
        dq[++dr] = i;
        maxi[i][j] = a[dq[st]][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++)
    {
        int stmin = 1, stmax = 1, drmin = 0, drmax = 0;
        /*
        minime.clear ();
        maxime.clear ();
        */
        for (int j = 1; j <= m; j++)
        {
            if (stmin <= drmin && minime[stmin] == j - dx)
            {
                stmin++;
            }
            while (stmin <= drmin && mini[i][minime[drmin]] >= mini[i][j])
            {
                drmin--;
            }
            if (stmax <= drmax && maxime[stmax] == j - dx)
            {
                stmax++;
            }
            while (stmax <= drmax && maxi[i][maxime[drmax]] <= maxi[i][j])
            {
                drmax--;
            }
            minime[++drmin] = j;
            maxime[++drmax] = j;
            /*
            minime.push_back (j);
            maxime.push_back (j);
            */
            if (j < dx)
                continue;
            int rez = maxi[i][maxime[stmax]] - mini[i][minime[stmin]];
            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;
}