Cod sursa(job #2675390)

Utilizator Alex_AeleneiAlex Aelenei Ioan Alex_Aelenei Data 21 noiembrie 2020 16:04:15
Problema Struti Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.78 kb
#include <deque>
#include <fstream>
#include <iostream>

using namespace std;

deque <int> dmn, dmx;
const int NMAX = 1e3;
int a[NMAX + 5][NMAX + 5];
int mn[NMAX + 5][NMAX + 5], mx[NMAX + 5][NMAX + 5];
int amn[NMAX + 5][NMAX + 5], amx[NMAX + 5][NMAX + 5];
int n, m;

inline void print_decks(void)
{
    deque <int> aux1 = dmn;
    deque <int> aux2 = dmx;

    printf("mins:");
    while(!aux1.empty())
    {
        printf("%d ", aux1.front());
        aux1.pop_front();
    }
    printf("\n");
    printf("maxs:");
    while(!aux2.empty())
    {
        printf("%d ", aux2.front());
        aux2.pop_front();
    }
    printf("\n");
}

inline void elim(int poz)
{
    while(!dmn.empty() && dmn.front() < poz)
        dmn.pop_front();
    while(!dmx.empty() && dmx.front() < poz)
        dmx.pop_front();
}

inline pair<int, int> query(int x, int y)
{
    int i, j, nr = 1e6, cnt = 0;

    for(i = 1; i <= n; ++ i)
    {
        dmn.clear();
        dmx.clear();

        for(j = 1; j <= y; ++ j)
        {
            while(!dmn.empty() && a[i][dmn.back()] > a[i][j])
                dmn.pop_back();
            while(!dmx.empty() && a[i][dmx.back()] < a[i][j])
                dmx.pop_back();
            dmn.push_back(j);
            dmx.push_back(j);
        }
        mn[i][1] = a[i][dmn.front()];
        mx[i][1] = a[i][dmx.front()];

        for(j = y + 1; j <= m; ++ j)
        {
            elim(j - y + 1);
            while(!dmn.empty() && a[i][dmn.back()] > a[i][j])
                dmn.pop_back();
            while(!dmx.empty() && a[i][dmx.back()] < a[i][j])
                dmx.pop_back();
            dmn.push_back(j);
            dmx.push_back(j);
            mn[i][j - y + 1] = a[i][dmn.front()];
            mx[i][j - y + 1] = a[i][dmx.front()];
        }
    }

    for(j = 1; j <= m - y + 1; ++ j)
    {
        dmn.clear();
        dmx.clear();

        for(i = 1; i <= x; ++ i)
        {
            while(!dmn.empty() && mn[dmn.back()][j] > mn[i][j])
                dmn.pop_back();
            while(!dmx.empty() && mx[dmx.back()][j] < mx[i][j])
                dmx.pop_back();
            dmn.push_back(i);
            dmx.push_back(i);
        }
        amn[1][j] = mn[dmn.front()][j];
        amx[1][j] = mx[dmx.front()][j];

        for(i = x + 1; i <= n; ++ i)
        {
            elim(i - x + 1);
            while(!dmn.empty() && mn[dmn.back()][j] > mn[i][j])
                dmn.pop_back();
            while(!dmx.empty() && mx[dmx.back()][j] < mx[i][j])
                dmx.pop_back();
            dmn.push_back(i);
            dmx.push_back(i);
            amn[i - x + 1][j] = mn[dmn.front()][j];
            amx[i - x + 1][j] = mx[dmx.front()][j];
        }
    }

    for(i = 1; i <= n - x + 1; ++ i)
        for(j = 1; j <= m - y + 1; ++ j)
        {
            if(amx[i][j] - amn[i][j] < nr)
                nr = amx[i][j] - amn[i][j], cnt = 0;
            if(amx[i][j] - amn[i][j] == nr)
                ++ cnt;
        }

    return make_pair(nr, cnt);
}

int main()
{
    ifstream in("struti.in");
    ofstream out("struti.out");

    int k, i, j, x, y;
    pair<int, int> ans1, ans2;
    in >> n >> m >> k;

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

    for(i = 1; i <= k; ++ i)
    {
        in >> x >> y;
        ans1 = query(x, y);
        if(x != y)
        {
            ans2 = query(y, x);
            if(ans1.first == ans2.first)
                out << ans1.first << ' ' << ans1.second + ans2.second << '\n';
            else
                out << max(ans1, ans2).first << ' ' << max(ans1, ans2).second << '\n';
        }
        else
            out << ans1.first << ' ' << ans1.second << '\n';
    }

    return 0;
}