Cod sursa(job #2802181)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 17 noiembrie 2021 18:21:37
Problema Struti Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.71 kb
#include <stdio.h>
#include <deque>

#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("03")
#pragma GCC optimize("O3")

char buff[ ( 1 << 7 ) ];
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> lin_max[ MAX ], col_max;
std::deque<short> lin_min[ MAX ], col_min;
short a[ MAX ][ MAX ], m, n;
short val_max[ MAX ][ MAX ];
short val_min[ MAX ][ MAX ];
short linMax[ MAX ];
short linMin[ MAX ];

short minn, no;

void reset() {
    minn = 10000;
    no = 0;
}

void fac( short l1, short l2 ) {
    short dif;
    for( short l = 0; l < n; l++ ) {
        col_max.clear();
        col_min.clear();
        for( short c = 0; c < m; c++ ) {
            while( !col_min.empty() && a[ l ][ col_min.back() ] >= a[ l ][ c ] )
                col_min.pop_back();
            col_min.push_back( c );
            if( c - col_min.front() == l1 )
                col_min.pop_front();

            while( !col_max.empty() && a[ l ][ col_max.back() ] <= a[ l ][ c ] )
                col_max.pop_back();
            col_max.push_back( c );
            if( c - col_max.front() == l1 )
                col_max.pop_front();

            val_min[ l ][ c ] = a[ l ][ col_min.front() ];
            val_max[ l ][ c ] = a[ l ][ col_max.front() ];
            if( c >= l1 - 1 ) {
                while( !lin_min[ c ].empty() && val_min[ lin_min[ c ].back() ][ c ] >= val_min[ l ][ c ] )
                    lin_min[ c ].pop_back();
                lin_min[ c ].push_back( l );
                if( l - lin_min[ c ].front() == l2 )
                    lin_min[ c ].pop_front();

                while( !lin_max[ c ].empty() && val_max[ lin_max[ c ].back() ][ c ] <= val_max[ l ][ c ] )
                    lin_max[ c ].pop_back();
                lin_max[ c ].push_back( l );
                if( l - lin_max[ c ].front() == l2 )
                    lin_max[ c ].pop_front();

                if( l >= l2 - 1 ) {
                    dif = val_max[ lin_max[ c ].front() ][ c ] - val_min[ lin_min[ c ].front() ][ c ];
                    if( dif < minn )
                        minn = dif, no = 1;
                    else if( dif == minn )
                        ++no;
                }
            }
        }
    }
    for( short c = 0; c < m; c++ ) {
        lin_min[ c ].clear();
        lin_max[ c ].clear();
    }
}

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 );
        short rez_no = no;
        short rez_min = minn;
        if( l2 != l1 ) {
            reset();
            fac( l2, l1 );
            if( rez_min == minn )
                rez_no += no;
            else if( rez_min > minn )
                rez_min = minn, rez_no = no;
        }
        fprintf( fout, "%d %d\n", rez_min, rez_no );
    }

    fclose( fin );
    fclose( fout );
    return 0;
}