Cod sursa(job #2811912)

Utilizator vladutzu_finutzuVlad Cacenschi vladutzu_finutzu Data 3 decembrie 2021 16:25:18
Problema Struti Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <fstream>
#include <deque>
#include <climits>
using namespace std;
ifstream cin("struti.in");
ofstream cout("struti.out");
const int NMAX = 1005;
int n, m, a[NMAX][NMAX], miniC[NMAX][NMAX], maxiC[NMAX][NMAX], miniL[NMAX][NMAX], maxiL[NMAX][NMAX], p;
deque<int> dqMax, dqMin;

void getMax(int k)
{
    for (int i = 1; i <= n; i++)
    {
        dqMax.clear();
        dqMin.clear();
        for (int j = 1; j <= m; j++)
        {
            while (!dqMax.empty() and a[i][j] >= a[i][dqMax.back()])
                dqMax.pop_back();

            while (!dqMin.empty() and a[i][j] <= a[i][dqMin.back()])
                dqMin.pop_back();

            dqMax.push_back(j);
            dqMin.push_back(j);

            if (dqMax.front() == j - k)
                dqMax.pop_front();

            if (dqMin.front() == j - k)
                dqMin.pop_front();

            maxiC[i][j] = a[i][dqMax.front()];
            miniC[i][j] = a[i][dqMin.front()];
        }
    }
}

int main()
{
    cin >> n >> m >> p;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> a[i][j];

    for (int x = 1; x <= p; x++)
    {
        int l, c, sol = INT_MAX, cnt = 0;
        cin >> l >> c;

        getMax(c);

        for (int j = 1; j <= m; j++)
        {
            dqMax.clear();
            dqMin.clear();
            for (int i = 1; i <= n; i++)
            {
                while (!dqMax.empty() and maxiC[i][j] >= maxiC[dqMax.back()][j])
                    dqMax.pop_back();

                while (!dqMin.empty() and miniC[i][j] <= miniC[dqMin.back()][j])
                    dqMin.pop_back();

                dqMax.push_back(i);
                dqMin.push_back(i);

                if (dqMax.front() == i - l)
                    dqMax.pop_front();

                if (dqMin.front() == i - l)
                    dqMin.pop_front();

                miniL[i][j] = miniC[dqMin.front()][j];
                maxiL[i][j] = maxiC[dqMax.front()][j];

                if (i >= l and j >= c)
                {
                    if (maxiL[i][j] - miniL[i][j] < sol)
                        sol = maxiL[i][j] - miniL[i][j], cnt = 1;
                    else if (maxiL[i][j] - miniL[i][j] == sol)
                        cnt++;
                }
            }
        }
        if(l == c)
        {
            cout<<sol<<" "<<cnt<<'\n';
            continue;
        }

        getMax(l);

        for (int j = 1; j <= m; j++)
        {
            dqMax.clear();
            dqMin.clear();
            for (int i = 1; i <= n; i++)
            {
                while (!dqMax.empty() and maxiC[i][j] >= maxiC[dqMax.back()][j])
                    dqMax.pop_back();

                while (!dqMin.empty() and miniC[i][j] <= miniC[dqMin.back()][j])
                    dqMin.pop_back();

                dqMax.push_back(i);
                dqMin.push_back(i);

                if (dqMax.front() == i - c)
                    dqMax.pop_front();

                if (dqMin.front() == i - c)
                    dqMin.pop_front();

                miniL[i][j] = miniC[dqMin.front()][j];
                maxiL[i][j] = maxiC[dqMax.front()][j];

                if (i >= c and j >= l)
                {
                    if (maxiL[i][j] - miniL[i][j] < sol)
                        sol = maxiL[i][j] - miniL[i][j], cnt = 1;
                    else if (maxiL[i][j] - miniL[i][j] == sol)
                        cnt++;
                }
            }
        }
        
        cout << sol << " " << cnt << '\n';
    }
    return 0;
}