Cod sursa(job #2802331)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 17 noiembrie 2021 22:14:15
Problema Struti Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3 kb
#include <stdio.h>
#include <deque>
 
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")
 
char buff[ ( 1 << 10 ) ];
FILE *fin;
 
short poz;
char nextChar() {
    if( poz == sizeof( buff ) ) {
        fread( buff, 1, sizeof( buff ), fin );
        poz = 0;
    }
 
    return buff[ poz++ ];
}
 
bool f[ 100 ];
short readshort() {
    short rez = 0;
    int ch;
    while( !f[ ch = nextChar() ] );
    do
        rez = rez * 10 + ch - '0';
    while( f[ ch = nextChar() ] );
 
    return rez;
}
 
#define MAX 1001
 
std::deque<short> qmax;
std::deque<short> qmin;
short a[ MAX ][ MAX ], m, n;
short val_max[ MAX ][ MAX ];
short val_min[ MAX ][ MAX ];
short minn, no;
 
static inline void reset() {
    minn = 10000;
    no = 0;
}
 
void fac( short l1, short l2 ) {
    short dif;
    for( short l = 0; l < n; l++ ) {
        qmax.clear();
        qmin.clear();
        for( short c = 0; c < m; c++ ) {
            while( !qmin.empty() && a[ l ][ qmin.back() ] >= a[ l ][ c ] )
                qmin.pop_back();
            qmin.push_back( c );
            if( c - qmin.front() == l1 )
                qmin.pop_front();
 
            while( !qmax.empty() && a[ l ][ qmax.back() ] <= a[ l ][ c ] )
                qmax.pop_back();
            qmax.push_back( c );
            if( c - qmax.front() == l1 )
                qmax.pop_front();
 
            val_min[ l ][ c ] = a[ l ][ qmin.front() ];
            val_max[ l ][ c ] = a[ l ][ qmax.front() ];
        }
    }

    for( int c = l1 - 1; c < m; c++ ) {
        qmax.clear();
        qmin.clear();
        for( int l = 0; l < n; l++ ) {
            while( !qmin.empty() && val_min[ qmin.back() ][ c ] >= val_min[ l ][ c ] )
                qmin.pop_back();
            qmin.push_back( l );
            if( l - qmin.front() == l2 )
                qmin.pop_front();

            while( !qmax.empty() && val_max[ qmax.back() ][ c ] <= val_max[ l ][ c ] )
                qmax.pop_back();
            qmax.push_back( l );
            if( l - qmax.front() == l2 )
                qmax.pop_front();
            if( l >= l2 - 1 ) {
                dif = val_max[ qmax.front() ][ c ] - val_min[ qmin.front() ][ c ];
                if( dif < minn )
                    minn = dif, no = 1;
                else if( dif == minn )
                    ++no;
            }
        }
    }
}
 
int main()
{
    short q;
    f[ '0' ] = f[ '1' ] = f[ '2' ] = f[ '3' ] = f[ '4' ] = 1;
    f[ '6' ] = f[ '7' ] = f[ '8' ] = f[ '9' ] = f[ '5' ] = 1;
    fin = fopen( "struti.in", "r" );
    n = readshort();
    m = readshort();
    q = readshort();
 
    for( short l = 0; l < n; l++ )
        for( short c = 0; c < m; c++ )
            a[ l ][ c ] = readshort();
 
    short l1, l2;
    short rez_min, rez_no;
    FILE *fout = fopen( "struti.out", "w" );
    while( q-- ) {
        l1 = readshort();
        l2 = readshort();
        reset();
        fac( l1, l2 );

        if( l2 != l1 )
            fac( l2, l1 );
        fprintf( fout, "%d %d\n", minn, no );
    }
 
    fclose( fin );
    fclose( fout );
    return 0;
}