Cod sursa(job #2797793)

Utilizator pielevladutPiele Vladut Stefan pielevladut Data 10 noiembrie 2021 16:43:53
Problema 2SAT Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.72 kb
#include <bits/stdc++.h>

using namespace std;

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

const int LGMAX = 1000;

int n, m, p;
int difmin, cnt;
int v[LGMAX + 5][LGMAX + 5];
int lmin[LGMAX + 5][LGMAX + 5];
int lmax[LGMAX + 5][LGMAX + 5];
int vmax[LGMAX + 5][LGMAX + 5];
int vmin[LGMAX + 5][LGMAX + 5];

void Solve(int lin, int col)
{
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
        {
            lmin[i][j] = 0;
            lmax[i][j] = 0;
            vmin[i][j] = 0;
            vmax[i][j] = 0;
        }
    }
    /// aici fac minim pt fiecare linie
    for(int i = 1; i <= n; i ++)
    {
        deque <int> dq;
        for(int j = 1; j <= m; j ++)
        {
            while(!dq.empty() && v[i][dq.back()] >= v[i][j])
            {
                dq.pop_back();
            }
            dq.push_back(j);
            if(j - dq.front() >= col)
            {
                dq.pop_front();
            }
            if(dq.back() >= col)
            {
                lmin[i][j] = v[i][dq.front()];
            }
        }
    }
    /// aici fac maxim pt fiecare linie
    for(int i = 1; i <= n; i ++)
    {
        deque <int> dq;
        for(int j = 1; j <= m; j ++)
        {
            while(!dq.empty() && v[i][dq.back()] <= v[i][j])
            {
                dq.pop_back();
            }
            dq.push_back(j);
            if(j - dq.front() >= col)
            {
                dq.pop_front();
            }
            if(dq.back() >= col)
            {
                lmax[i][j] = v[i][dq.front()];
            }
        }
    }
    /// aici fac minim v[i][j] = min(toate submatricile de dimensiune lin, col cu elementul din dreapta jos = i, j)
    for(int i = col; i <= m; i ++)
    {
        deque <int> dq;
        for(int j = 1; j <= n; j ++)
        {
            while(!dq.empty() && lmin[dq.back()][i] >= lmin[j][i])
            {
                dq.pop_back();
            }
            dq.push_back(j);
            if(j - dq.front() >= lin)
            {
                dq.pop_front();
            }
            if(j >= lin)
            {
                vmin[j][i] = lmin[dq.front()][i];
            }
        }
    }
    /// aici fac maxim v[i][j] = max(toate submatricile de dimensiune lin, col cu elementul din dreapta jos = i, j)
    for(int i = col; i <= m; i ++)
    {
        deque <int> dq;
        for(int j = 1; j <= n; j ++)
        {
            while(!dq.empty() && lmax[dq.back()][i] <= lmax[j][i])
            {
                dq.pop_back();
            }
            dq.push_back(j);
            if(j - dq.front() >= lin)
            {
                dq.pop_front();
            }
            if(j >= lin)
            {
                vmax[j][i] = lmax[dq.front()][i];
            }
        }
    }
    for(int i = lin; i <= n; i ++)
    {
        for(int j = col; j <= m; j ++)
        {
            if(vmax[i][j] - vmin[i][j] < difmin)
            {
                difmin = vmax[i][j] - vmin[i][j];
                cnt = 1;
            }
            else
            {
                if(vmax[i][j] - vmin[i][j] == difmin)
                {
                    cnt++;
                }
            }
        }
    }
}

int main()
{
    fin >> n >> m >> p;
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= m; j ++)
        {
            fin >> v[i][j];
        }
    }
    while(p--)
    {
        int l, c;
        fin >> l >> c;
        difmin = 1e9;
        cnt = 0;
        Solve(l, c);
        if(l != c)
        {
            Solve(c, l);
        }
        fout << difmin << ' ' << cnt << '\n';
    }
    return 0;
}