Cod sursa(job #2811830)

Utilizator Razvan_GabrielRazvan Gabriel Razvan_Gabriel Data 3 decembrie 2021 09:29:06
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <iostream>
#include <fstream>
#include <deque>

using namespace std;

const int INF = 1e4;

int nl, nc, a[1001][1001], mini[1001][1001], maxi[1001][1001];
int d[1001], dmax[1001], dmin[1001];

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

void coloana_mini(int c, int dy)
{
    int st = 0, dr = -1;
    for (int i = 0; i < nl; i++)
    {
        if (st <= dr && d[st] == i - dy)
            st++;

        while (st <= dr && a[d[dr]][c] >= a[i][c])
            dr--;

        d[++dr] = i;
        mini[i][c] = a[d[st]][c];
    }
}

void calcul_mini(int dy)
{
    for (int j = 0; j < nc; j++)
        coloana_mini(j, dy);

}

void coloana_maxi(int c, int dy)
{
    int st = 0, dr = -1;
    for (int i = 0; i < nl; i++)
    {
        if (st <= dr && d[st] == i - dy)
            st++;

        while (st <= dr && a[d[dr]][c] <= a[i][c])
            dr--;

        d[++dr] = i;
        maxi[i][c] = a[d[st]][c];
    }
}

void calcul_maxi(int dy)
{
    for (int j = 0; j < nc; j++)
        coloana_maxi(j, dy);
}

void diferenta_min(int dx, int dy, int &dif_min, int &nr)
{
    calcul_mini(dy);
    calcul_maxi(dy);
    int stmax = 0, drmax = -1, stmin = 0, drmin = -1;
    for (int i = dy - 1; i < nl; i++){
        stmax = stmin = 0;
        drmax = drmin = -1;
        for (int j = 0; j < nc; j++){
            if (stmin <= drmin && dmin[stmin] == j - dx)
                stmin++;

            while (stmin <= drmin && mini[i][dmin[drmin]] >= mini[i][j])
                drmin--;

            dmin[++drmin] = j;
            if (stmax <= drmax && dmax[stmax] == j - dx)
                stmax++;

            while (stmax <= drmax && maxi[i][dmax[drmax]] <= maxi[i][j])
                drmax--;

            dmax[++drmax] = j;
            if (j < dx - 1) continue;
            int rez_actual = maxi[i][dmax[stmax]] - mini[i][dmin[stmin]];
            if (rez_actual < dif_min)
            {
                dif_min = rez_actual;
                nr = 1;
            }
            else if (rez_actual == dif_min)
                nr++;

        }
    }
}

void calcul(int dx, int dy)
{
    int difmin = INF;
    int nr;
    diferenta_min(dx, dy, difmin, nr);
    if (dx != dy)
        diferenta_min(dy, dx, difmin, nr);

    fout << difmin << " " << nr << "\n";
}

int main()
{

    int p;
    fin >> nl >> nc >> p;
    for (int i = 0; i < nl; i++)
        for (int j = 0; j < nc; j++)
            fin >> a[i][j];

    for (int i = 0; i < p; i++){
        int dx, dy;
        fin >> dx >> dy;
        calcul(dx, dy);
    }

    return 0;
}