Cod sursa(job #2041229)

Utilizator dragomirmanuelDragomir Manuel dragomirmanuel Data 16 octombrie 2017 22:51:41
Problema Struti Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <iostream>
#include <cstdio>
#include <deque>

using namespace std;

const int NMax = 1005;
const int inf = 0x3f3f3f3f;

int M, N, dx, dy, teste;
int m_init[NMax][NMax], m_min[NMax][NMax], m_max[NMax][NMax];
deque < int > dq_min, dq_max;
pair < int, int > sol; // { minim, nr_ap_minim }

void Read()
{
    scanf("%d %d %d", &M, &N, &teste);

    for(int i=1; i<=M; ++i)
        for(int j=1; j<=N; ++j)
            scanf("%d", &m_init[i][j]);
}

void Calc()
{
    for(int vf = 1; vf <=2; ++vf)
    {
        for(int i=1; i<=M; ++i)
        {
            for(int j=1; j<=N; ++j)
            {
                if(!dq_min.empty() && j-dq_min.front() >= dy)
                    dq_min.pop_front();

                if(!dq_max.empty() && j-dq_max.front() >= dy)
                    dq_max.pop_front();

                while(!dq_min.empty() && m_init[i][j] <= m_init[i][dq_min.back()])
                    dq_min.pop_back();

                while(!dq_max.empty() && m_init[i][j] >= m_init[i][dq_max.back()])
                    dq_max.pop_back();

                dq_min.push_back(j);
                dq_max.push_back(j);

                m_min[i][j] = m_init[i][dq_min.front()];
                m_max[i][j] = m_init[i][dq_max.front()];
            }

            while(!dq_min.empty())
                dq_min.pop_back();

            while(!dq_max.empty())
                dq_max.pop_back();
        }

        for(int j = dy; j<=N; ++j)
        {
            for(int i=1; i<=M; ++i)
            {
                if(!dq_min.empty() && i-dq_min.front() >= dx)
                    dq_min.pop_front();

                if(!dq_max.empty() && i-dq_max.front() >= dx)
                    dq_max.pop_front();

                while(!dq_min.empty() && m_min[i][j] <= m_min[dq_min.back()][j])
                    dq_min.pop_back();

                while(!dq_max.empty() && m_max[i][j] >= m_init[dq_max.back()][j])
                    dq_max.pop_back();

                dq_min.push_back(i);
                dq_max.push_back(i);

                if(i>=dx)
                {
                    int nr1 = m_max[dq_max.front()][j];
                    int nr2 = m_min[dq_min.front()][j];

                    if(nr1 - nr2 < sol.first)
                    {
                        sol.first = nr1 - nr2;
                        sol.second = 1;
                    }

                    else if(nr1 - nr2 == sol.first)
                    {
                        ++sol.second;
                    }
                }
            }

            while(!dq_min.empty())
                dq_min.pop_back();

            while(!dq_max.empty())
                dq_max.pop_back();
        }

        if(dx != dy)
            swap(dx, dy);
        else
            break;
    }

}

void Solve()
{
    for(int i=1; i<=teste; ++i)
    {
        scanf("%d %d", &dx, &dy);
        sol.first = inf;
        sol.second = 0;
        Calc();
        printf("%d %d\n", sol.first, sol.second);
    }
}

int main()
{
    freopen("struti.in", "r", stdin);
    freopen("struti.out", "w", stdout);

    Read();
    Solve();
    return 0;
}