Cod sursa(job #3226157)

Utilizator BuzdiBuzdugan Rares Andrei Buzdi Data 20 aprilie 2024 12:07:48
Problema Struti Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <fstream>
#include <stack>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#define ll long long

using namespace std;

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

const int NMAX = 1000;
const int INF = 1e9;

int n, m, T, min_dif, cnt_min_dif;
int a[NMAX + 1][NMAX + 1];
int maxi[NMAX + 1][NMAX + 1];
int mini[NMAX + 1][NMAX + 1];
int tmp[NMAX + 1][NMAX + 1];

void GetMax(int dx, int dy, int b[][NMAX + 1], int c[][NMAX + 1])
{
    for(int i = 1; i <= n; i++)
    {
        deque<int> dq;
        for(int j = 1; j <= m; j++)
        {
            while(!dq.empty() && dq.back() < j - dy + 1)
                dq.pop_back();
            while(!dq.empty() && a[i][j] > a[i][dq.front()])
                dq.pop_front();
            dq.push_front(j);

            b[i][j] = a[i][dq.back()];
        }
    }

    for(int j = 1; j <= m; j++)
    {
        deque<int> dq;
        for(int i = 1; i <= n; i++)
        {
            while(!dq.empty() && dq.back() < i - dx + 1)
                dq.pop_back();
            while(!dq.empty() && b[i][j] > b[dq.front()][j])
                dq.pop_front();
            dq.push_front(i);

            c[i][j] = b[dq.back()][j];
        }
    }
}

void GetMin(int dx, int dy, int b[][NMAX + 1], int c[][NMAX + 1])
{
    for(int i = 1; i <= n; i++)
    {
        deque<int> dq;
        for(int j = 1; j <= m; j++)
        {
            while(!dq.empty() && dq.back() < j - dy + 1)
                dq.pop_back();
            while(!dq.empty() && a[i][j] < a[i][dq.front()])
                dq.pop_front();
            dq.push_front(j);

            b[i][j] = a[i][dq.back()];
        }
    }

    for(int j = 1; j <= m; j++)
    {
        deque<int> dq;
        for(int i = 1; i <= n; i++)
        {
            while(!dq.empty() && dq.back() < i - dx + 1)
                dq.pop_back();
            while(!dq.empty() && b[i][j] < b[dq.front()][j])
                dq.pop_front();
            dq.push_front(i);

            c[i][j] = b[dq.back()][j];
        }
    }
}

void Solve(int dx, int dy)
{
    GetMax(dx, dy, tmp, maxi);
    GetMin(dx, dy, tmp, mini);

    for(int i = dx; i <= n; i++)
        for(int j = dy; j <= m; j++)
            if(maxi[i][j] - mini[i][j] < min_dif) {
                min_dif = maxi[i][j] - mini[i][j];
                cnt_min_dif = 1;
            }
            else if(maxi[i][j] - mini[i][j] == min_dif)
                cnt_min_dif++;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

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

    while(T--)
    {
        int dx, dy;
        cin >> dx >> dy;

        min_dif = INF;
        cnt_min_dif = 0;

        Solve(dx, dy);
        if(dx != dy)
            Solve(dy, dx);

        cout << min_dif << ' ' << cnt_min_dif << '\n';
    }

    return 0;
}