Cod sursa(job #1100374)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 6 februarie 2014 20:43:21
Problema Struti Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.38 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;
}