Cod sursa(job #1967451)

Utilizator DysKodeTurturica Razvan DysKode Data 16 aprilie 2017 17:52:09
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.53 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("arbint.in");
ofstream fout("arbint.out");

#define f first
#define s second

int W[100010],use[100010],father[100010],tag[100010],pos[100010],i,j,n,nivel[100010],first[100010],x,y,m,nrLanturi,r,v[100010],t;
int a[100010],b[100010],k,ANS;
vector< pair<int,int> > G[100010];
vector< int > lant[100010];

struct SegTree
{
    int n,*v,ans;
    SegTree( int siz )
    {
        n = siz;
        v = new int[ 4 * n ];
        memset( v , 0 , sizeof( v ) );
    }
    void UPD( int nod, int left, int right, int poz, int val )
    {
        int middle = ( left + right ) / 2;
        if( left == right )
        {
            v[ nod ] = val;
            return;
        }
        if( poz <= middle )
            UPD( 2 * nod , left , middle , poz , val );
        else
            UPD( 2 * nod + 1 , middle + 1 , right , poz , val );
        v[ nod ] = max( v[ 2 * nod ] , v[ 2 * nod + 1 ] );
    }
    void Update( int poz, int val )
    {
        UPD( 1 , 1 , n , poz , val );
    }
    int QR( int nod, int left, int right, int L, int R )
    {
        int middle = ( left + right ) / 2;
        if( left > R || right < L )
            return 0;
        if( L <= left && right <= R )
            return v[ nod ];
        return max( QR( 2 * nod , left , middle , L , R ) ,
                    QR( 2 * nod + 1 , middle + 1 , right , L , R ) );
    }
    int Query( int L, int R )
    {
        return QR( 1 , 1 , n , L , R );
    }
}*arb[ 100010 ];

void DF1( int nod , int ftr )
{
    use[ nod ] = 1;
    W[ nod ] = 1;
    father[ nod ] = ftr;
    nivel[ nod ] = nivel[ ftr ] + 1;
    for( int i = 0 ; i < G[ nod ].size() ; i++ )
    {
        if( !use[ G[ nod ][ i ].s ] )
        {
            DF1( G[ nod ][ i ].s , nod );
            W[ nod ] += W[ G[ nod ][ i ].s ];
            G[ nod ][ i ].f = W[ G[ nod ][ i ].s ];
        }
    }
    sort( G[ nod ].begin() , G[ nod ].end() );
}

void DF2( int nod )
{
    lant[ nrLanturi ].push_back( nod );
    tag[ nod ] = nrLanturi;
    pos[ nod ] = lant[ nrLanturi ].size() - 1;
    first[ nrLanturi ] = lant[ nrLanturi ][ 1 ];
    if( G[ nod ].size() == 1 && nod != 1 )
    {
        arb[ nrLanturi ] = new SegTree( pos[ nod ] );
        for( auto it : lant[ nrLanturi ] )
            (*arb[ nrLanturi ]).Update( pos[ it ] , v[ it ] );
        nrLanturi++;
        lant[ nrLanturi ].push_back( 0 );
    }
    for( int i = G[ nod ].size() - 1 ; i >= 0 ; i-- )
    {
        if( G[ nod ][ i ].s == father[ nod ] )
            continue;
        DF2( G[ nod ][ i ].s );
    }
}

void drum( int nod, int a[] )
{
    if( tag[ nod ] == 0 )
        return;
    drum( father[ first[ tag[ nod ] ] ] , a );
    a[ ++a[ 0 ] ] = nod;
}

void solve( int nod )
{
    if( nivel[ nod ] < nivel[ k ] )
        return;
    if( nivel[ first[ tag[ nod ] ] ] >= nivel[ k ] )
        ANS = max( ANS , (*arb[ tag[ nod ] ]).Query( 1 , pos[ nod ] ) );
    else if( nivel[ first[ tag[ nod ] ] ] < nivel[ k ] )
        ANS = max( ANS , (*arb[ tag[ nod ] ]).Query( pos[ k ] , pos[ nod ] ) );
    solve( father[ first[ tag[ nod ] ] ] );
}

int main()
{
    fin>>n>>m;
    arb[ 0 ] = new SegTree( n );
    for( i = 1 ; i <= n ; i++ )
    {
        fin>>x;
        (*arb[0]).Update( i , x );
    }
    for( i = 1 ; i <= m ; i++ )
    {
        fin>>t>>x>>y;
        if( t == 0 )
            fout<<(*arb[0]).Query( x , y )<<'\n';
        else
            (*arb[0]).Update( x , y );
    }
return 0;
}