Cod sursa(job #2145609)

Utilizator robx12lnLinca Robert robx12ln Data 27 februarie 2018 14:45:04
Problema Struti Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.09 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin("struti.in");
ofstream fout("struti.out");
int N, M, P, A[1005][1005], MAX[1005][1005], MIN[1005][1005];
deque<int> D[1005], d;
vector<int> V;
inline void reset(){
    for( int i = 1; i <= N; i++ )
        for( int j = 1; j <= M; j++ )
            MAX[i][j] = -1;
    for( int i = 1; i <= N; i++ )
        for( int j = 1; j <= M; j++ )
            MIN[i][j] = (1<<15) - 1;
}
inline void solve_MAX( int X, int Y ){
    for( int j = 1; j <= M; j++ )
        D[j].clear();
    for( int j = 1; j <= M; j++ ){
        for( int i = 1; i < X; i++ ){
            while( !D[j].empty() && A[ D[j].back() ][j] < A[i][j] )
                D[j].pop_back();
            D[j].push_back( i );
        }
    }
    for( int i = X; i <= N; i++ ){
        V.clear();
        for( int j = 1; j <= M; j++ ){
            while( !D[j].empty() && A[ D[j].back() ][j] < A[i][j] )
                D[j].pop_back();
            D[j].push_back( i );
            if( i - D[j].front() == X )
                D[j].pop_front();
            V.push_back( A[ D[j].front() ][j] );
        }
        d.clear();
        for( int j = 1; j < Y; j++ ){
            while( !d.empty() && V[ d.back() - 1 ] < V[j - 1] )
                d.pop_back();
            d.push_back( j );
        }
        for( int j = Y; j <= M; j++ ){
            while( !d.empty() && V[ d.back() - 1 ] < V[j - 1] )
                d.pop_back();
            d.push_back( j );
            if( j - d.front() == Y )
                d.pop_front();
            MAX[i][j] = V[ d.front() - 1 ];
        }
    }
    return;
}
inline void solve_MIN( int X, int Y ){
     for( int j = 1; j <= M; j++ )
        D[j].clear();
    for( int j = 1; j <= M; j++ ){
        for( int i = 1; i < X; i++ ){
            while( !D[j].empty() && A[ D[j].back() ][j] > A[i][j] )
                D[j].pop_back();
            D[j].push_back( i );
        }
    }
    for( int i = X; i <= N; i++ ){
        V.clear();
        for( int j = 1; j <= M; j++ ){
            while( !D[j].empty() && A[ D[j].back() ][j] > A[i][j] )
                D[j].pop_back();
            D[j].push_back( i );
            if( i - D[j].front() == X )
                D[j].pop_front();
            V.push_back( A[ D[j].front() ][j] );
        }
        d.clear();
        for( int j = 1; j < Y; j++ ){
            while( !d.empty() && V[ d.back() - 1 ] > V[j - 1] )
                d.pop_back();
            d.push_back( j );
        }
        for( int j = Y; j <= M; j++ ){
            while( !d.empty() && V[ d.back() - 1 ] > V[j - 1] )
                d.pop_back();
            d.push_back( j );
            if( j - d.front() == Y )
                d.pop_front();
            MIN[i][j] = V[ d.front() - 1 ];
        }
    }
    return;
}
inline pair<int,int> solve( int X, int Y ){
    reset();
    solve_MAX( X, Y );
    solve_MIN( X, Y );
    pair<int,int> Sol;
    Sol.first = (1<<15) - 1;
    Sol.second = 0;
    for( int i = X; i <= N; i++ ){
        for( int j = Y; j <= M; j++ ){
            if( Sol.first > MAX[i][j] - MIN[i][j] ){
                Sol.first = MAX[i][j] - MIN[i][j];
                Sol.second = 1;
            }else{
                if( Sol.first == MAX[i][j] - MIN[i][j] )
                    Sol.second++;
            }
        }
    }
    return Sol;
}
int main(){
    fin >> N >> M >> P;
    for( int i = 1; i <= N; i++ )
        for( int j = 1; j <= M; j++ )
            fin >> A[i][j];
    for( int i = 1; i <= P; i++ ){
        int X, Y; fin >> X >> Y;
        pair<int,int> S1 = solve( X, Y );
        if( X != Y ){
            pair<int,int> S2 = solve( Y, X );
            if( S1.first == S2.first )
                fout << S1.first << " " << S1.second + S2.second << "\n";
            else
                if( S1.first < S2.first )
                    fout << S1.first << " " << S1.second << "\n";
                else
                    fout << S2.first << " " << S2.second << "\n";
        }else
            fout << S1.first << " " << S1.second << "\n";
    }
    return 0;
}