Cod sursa(job #906884)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 7 martie 2013 12:41:12
Problema Struti Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <fstream>
#include <deque>

using namespace std;

const int MAX_N = 1002;

int N, M, T, R, C, Res, Nr;
int A[ MAX_N ][ MAX_N ], Min[ MAX_N ][ MAX_N ], Max[ MAX_N ][ MAX_N ];
deque < int > a, b;

inline void calc(int R, int C)
{
    while(!a.empty())
        a.pop_front();
    while(!b.empty())
        b.pop_front();

    for(int i = 1; i <= N; ++i)
    {
        while(!a.empty())
            a.pop_front();
        while(!b.empty())
            b.pop_front();
        for(int j = 1; j <= M; ++j)
        {
            while(!a.empty() && A[i][j] <= A[i][ a.back() ])
                a.pop_back();
            a.push_back(j);
            if(a.front() <= j-C)
                a.pop_front();
            if(j >= C)
                Min[i][j] = A[i][ a.front() ];

            while(!b.empty() && A[i][j] >= A[i][ b.back() ])
                b.pop_back();
            b.push_back(j);
            if(b.front() <= j-C)
                b.pop_front();
            if(j >= C)
                Max[i][j] = A[i][ b.front() ];
        }
    }

    for(int j = C; j <= M; ++j)
    {
        while(!a.empty())
            a.pop_front();
        while(!b.empty())
            b.pop_front();
        for(int i = 1; i <= N; ++i)
        {
            while(!a.empty() && Min[i][j] <= Min[ a.back() ][j])
                a.pop_back();
            a.push_back(i);
            if(a.front() <= i - R)
                a.pop_front();

            while(!b.empty() && Max[i][j] >= Max[ b.back() ][j])
                b.pop_back();
            b.push_back(i);
            if(b.front() <= i - R)
                b.pop_front();

            if(i >= R)
            {
                int t = Max[ b.front() ][j] - Min[ a.front() ][j];

                if(t < Res)
                    Res = t, Nr = 1;
                else if(t == Res)
                    ++Nr;
            }
        }

    }
}

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

    f >> N >> M >> T;
    for(int i = 1; i <= N; ++i)
        for(int j = 1; j <= M; ++j)
            f >> A[i][j];

    while(T)
    {
        f >> R >> C;

        Res = 9999999, Nr = 0;

        calc(R, C);
        if(R != C)
            calc(C, R);

        g << Res << " " << Nr << '\n';

        --T;
    }

    f.close();
    g.close();

    return 0;
}