Cod sursa(job #1147480)

Utilizator gedicaAlpaca Gedit gedica Data 19 martie 2014 21:17:59
Problema Struti Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 3.94 kb
#include <fstream>
#include <deque>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>

using namespace std;

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

const int NMAX= 1000, INF = (1<<20)+1;
int n, m, Q, Min= INF, cate= 0;

struct strut
{
    int poz, val;
};

int v[NMAX+1][NMAX+1];
deque <strut> d_min[NMAX+1], d_max[NMAX+1], df_min, df_max;

inline void initializare_c( int nush )
{
    for( int c= 1;  c<= m;  ++c )
    {
        d_min[c].clear();
        d_max[c].clear();
        for( int i= 1;  i<nush;  ++i )
        {
            strut aux;
            aux.val= v[i][c];
            aux.poz= i;
            while( !d_min[c].empty() && d_min[c].back().val > v[i][c] )
            {
                d_min[c].pop_back();
            }
            d_min[c].push_back( aux );
            while( !d_max[c].empty() && d_max[c].back().val < v[i][c] )
            {
                d_max[c].pop_back();
            }
            d_max[c].push_back( aux );
        }
    }
}

inline void initializare_l( int L )
{
    df_min.clear();
    df_max.clear();
    for( int c= 1;  c<L;  ++c )
    {
        strut aux;
        aux= d_min[c].front();
        aux.poz= c;
        while( !df_min.empty() && df_min.back().val > aux.val )
        {
            df_min.pop_back();
        }
        df_min.push_back( aux );
        aux= d_max[c].front();
        aux.poz= c;
        while( !df_max.empty() && df_max.back().val < aux.val )
        {
            df_max.pop_back();
        }
        df_max.push_back( aux );
    }
}

inline void rezolva_frumos_nu_jegos( int x, int y )
{
    initializare_c( x );
    initializare_l( y );
    for( int l= x;  l<=n;  l++ )
    {
        for( int c= 1;  c<=m;  c++ )
        {
            strut aux;
            aux.val= v[l][c];
            aux.poz= l;

            if( d_min[c].front().poz < l-x+1 )  d_min[c].pop_front();
            if( d_max[c].front().poz < l-x+1 )  d_max[c].pop_front();

            while( !d_min[c].empty() && d_min[c].back().val > v[l][c] )
            {
                d_min[c].pop_back();
            }
            d_min[c].push_back( aux );

            while( !d_max[c].empty() && d_max[c].back().val < v[l][c] )
            {
                d_max[c].pop_back();
            }
            d_max[c].push_back( aux );

        }

        initializare_l( y );

        for( int Col= y;  Col<=m;  Col++ )
        {
            if( df_min.front().poz < Col-y+1 )  df_min.pop_front();
            if( df_max.front().poz < Col-y+1 )  df_max.pop_front();

            strut aux;
            aux.val= d_min[Col].front().val;
            aux.poz= Col;

            while( !df_min.empty() && df_min.back().val > aux.val )
            {
                df_min.pop_back();
            }
            df_min.push_back( aux );

            aux.val= d_max[Col].front().val;
            aux.poz= Col;

            while( !df_max.empty() && df_max.back().val < aux.val )
            {
                df_max.pop_back();
            }

            df_max.push_back( aux );

            if( df_max.front().val - df_min.front().val < Min )
            {
                Min= df_max.front().val - df_min.front().val;
                cate= 0;
            }
            if( df_max.front().val - df_min.front().val == Min )  ++cate;
        }
    }
}

int main(  )
{
    f >> n >> m >> Q;
    //citeste
    for( int i= 1; i<=n; ++i )
    {
        for( int j= 1; j<=m; ++j )
        {
            f >> v[i][j];
        }
    }
    //citeste
    int x, y;
    for( int q= 0; q<Q; ++q )
    {
        f >> x >> y;
        Min= INF;
        cate= 0;
        rezolva_frumos_nu_jegos( x, y );
        if( x != y )
        {
            rezolva_frumos_nu_jegos( y, x );
        }
        g << Min << " " << cate << '\n';
    }
    return 0;
}