Cod sursa(job #411987)

Utilizator ssergiussSergiu-Ioan Ungur ssergiuss Data 5 martie 2010 11:53:34
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <algorithm>
using namespace std;

#define LOG_N 25
#define MAX_N 100005
#define MAX_S 10005

char s[ MAX_S ];
int N, M;
int cnt_s, a[ MAX_N ], rmq[ LOG_N ][ MAX_N ], log_2[ MAX_N ];

void calc_rmq() {

    int i, j, lim_sup;

    log_2[ 1 ] = 0;
    for( i = 2; i <= N; ++i )
        log_2[ i ] = log_2[ i>>1 ] + 1;

    for( i = 1; i <= N; ++i )
        rmq[ 0 ][ i ] = i;

    lim_sup = log_2[ N ];
    for( i = 1; i <= lim_sup; ++i )
        for( j = 1; j + (1<<i) - 1 <= N; ++j ) {

            rmq[ i ][ j ] = rmq[ i-1 ][ j ];
            if( a[ rmq[ i-1 ][ j + ( 1 << (i-1) ) ] ] < a[ rmq[ i ][ j ] ] )
                rmq[ i ][ j ] = rmq[ i-1 ][ j + ( 1 << (i-1) ) ];
        }
}

inline int calc_min( const int &x, const int &y ) {

    int sol, lim_sup;

    lim_sup = log_2[ y-x+1 ];

    sol = rmq[ lim_sup ][ x ];
    if( a[ rmq[ lim_sup ][ y - ( 1 << lim_sup ) + 1 ] ] < a[ sol ] )
        sol = rmq[ lim_sup ][ y - ( 1 << lim_sup ) + 1 ];

    return a[ sol ];
}

void read( int &val ) {

    while( !isdigit( s[ cnt_s ] ) )
        if( ++cnt_s == MAX_S ) {

            fread( s, 1, MAX_S, stdin );
            cnt_s = 0;
        }

    val = 0;
    while( isdigit( s[ cnt_s ] ) ) {

        val = val * 10 + s[ cnt_s ] - '0';
        if( ++cnt_s == MAX_S ) {

            fread( s, 1, MAX_S, stdin );
            cnt_s = 0;
        }
    }
}

int main() {

    freopen( "rmq.in", "r", stdin );
    freopen( "rmq.out", "w", stdout );

    int i, x, y;

    cnt_s = MAX_S - 1;

    read( N );
    read( M );

    for( i = 1; i <= N; ++i )
        read( a[ i ] );

    calc_rmq();

    while( M-- ) {

        read( x );
        read( y );

        printf( "%d\n", calc_min( x, y ) );
    }

    return 0;
}