Cod sursa(job #1180535)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 30 aprilie 2014 18:48:41
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.42 kb
#include <iostream>
#include <fstream>

using namespace std;

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 + 1];
            belong = new int[N + 1];

            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();
        }

        void free_memory()
        {
            delete d;
            delete st;
            delete dr;

            delete v;
            delete belong;
        }

        T combine( T a, T b ) const
        {
            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( const int pos, const 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] );
            }
        }

        inline T query( const int x, const int y ) const
        {
            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 )
            {
                sol = combine( sol, v[k] );
            }

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

            if ( apart_x != apart_y )
            {
                for ( int k = st[apart_y]; k <= min( dr[apart_y], y ); ++k )
                {
                    sol = combine( 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 + 1];
int N, M;

int main()
{
    ifstream f("arbint.in");
    ofstream g("arbint.out");

    f >> N >> M;

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

    SQRTD <int, maxim> R;

    R.alloc_memory( N, a );

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

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

    R.free_memory();

    return 0;
}