Cod sursa(job #1180520)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 30 aprilie 2014 18:40:33
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.94 kb
#include <iostream>
#include <fstream>

using namespace std;

const int BUFFER_SIZE = 1 << 20;
char buffer[BUFFER_SIZE];
int position = BUFFER_SIZE;

inline char getChar()
{
    if ( position == BUFFER_SIZE )
    {
        fread( buffer, 1, BUFFER_SIZE, stdin );
        position = 0;
    }

    return buffer[ position++ ];
}

inline int getInt()
{
    int nr = 0;
    char ch;

    do
    {
        ch = getChar();

    } while ( !isdigit( ch ) );

    do
    {
        nr = nr * 10 + ch - '0';
        ch = getChar();

    } while ( isdigit( ch ) );

    return nr;
}

template <class T, T(*F)(T,T)>
class SQRTD
{
    const int INF = 1e9;

    public:

        SQRTD(){ }

        SQRTD( const int n, T a[] )
        {
            alloc_memory( n, a );
        }

        void alloc_memory( const int n, T a[] )
        {
            N = n;
            v = new T[N + 2];
            belong = new int[N + 2];

            for ( int i = 1; i <= N; ++i )
            {
                v[i] = a[i];
                belong[i] = 0;
            }

            SQRT = 1;

            while ( SQRT * SQRT < N ) SQRT++;

            d = new T[SQRT + 2];
            st = new int[SQRT + 2];
            dr = new int[SQRT + 2];

            for ( int i = 1; i <= SQRT; ++i )
            {
                d[i] = -INF;
                st[i] = INF;
                dr[i] = 0;
            }

            for ( int i = 1, x = 0; i <= N; ++i )
            {
                if ( i % SQRT == 1 ) x++;

                belong[i] = x;
            }

            for ( int i = 1, x = 0; i <= N; ++i )
            {
                if ( i % SQRT == 1 ) x++;

                st[x] = min( st[x], i );
                dr[x] = max( dr[x], min( st[x] + SQRT - 1, N ) );
            }

            init_decomposition();
        }

        T combine( T a, T b )
        {
            if ( a == -INF ) a = b;
            else             a = F( a, b );

            return a;
        }

        void init_decomposition()
        {
            for ( int i = 1; i <= N; ++i )
            {
                d[ belong[i] ] = combine( d[ belong[i] ], v[i] );
            }
        }

        void update( int pos, T new_val )
        {
            v[pos] = new_val;

            int apart = belong[pos];

            d[apart] = -INF;

            for ( int x = st[apart]; x <= dr[apart]; ++x )
            {
                d[apart] = combine( d[apart], v[x] );
            }
        }

        T query( int x, int y )
        {
            int apart_x = belong[x];
            int apart_y = belong[y];

            T sol = -INF;

            for ( int k = max( st[apart_x], x ); k <= min( dr[apart_x], y ); ++k )
            {
                if ( sol == -INF ) sol = v[k];
                else               sol = F( sol, v[k] );
            }

            for ( int k = apart_x + 1; k <= apart_y - 1; ++k )
            {
                if ( sol == -INF ) sol = d[k];
                else               sol = F( sol, d[k] );
            }

            if ( apart_x != apart_y )
            {
                for ( int k = st[apart_y]; k <= min( dr[apart_y], y ); ++k )
                {
                    if ( sol == -INF ) sol = v[k];
                    else               sol = F( sol, v[k] );
                }
            }

            return sol;
        }

    private:

        T *v, *d;
        int *belong, *st, *dr;
        int N, SQRT;
};

int maxim( int a, int b )
{
    return max( a, b );
}

int a[100000 + 5];
int N, M;

int main()
{
    freopen("arbint.in", "r", stdin);
    freopen("arbout.out", "w", stdout);

    N = getInt();
    M = getInt();

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

    SQRTD <int, maxim> R( N, a );

    for ( int i = 1, a, b, c; i <= M; ++i )
    {
        a = getInt();
        b = getInt();
        c = getInt();

        if ( a == 0 )
        {
            printf("%d\n", R.query( b, c ) );
        }
        else
        {
            R.update( b, c );
        }
    }

    return 0;
}