Cod sursa(job #2410418)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 20 aprilie 2019 01:08:39
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.39 kb
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int NR = 100005 ;
ifstream in ("heavypath.in") ;
ofstream out ("heavypath.out") ;
vector < int > v [ NR ] , lant [ NR ] , aint [ NR ] ;
int n , q , c [ NR ] , nr_fii [ NR ] , lvl [ NR ] , nr_lant , pos [ NR ] ,w_l [ NR ] , father [ NR ] ;

void dfs ( int nod , int taticut )  {

    int node = 0 ;
    vector < int > :: iterator it ;
    nr_fii [ nod ] = 1 ;
    for ( it = v [ nod ].begin() ; it != v [ nod ].end() ; ++ it )  {
        if ( *it == taticut )   continue ;
        lvl [ *it ] = lvl [ nod ] + 1 ;
        dfs( *it , nod ) ;
        nr_fii [ nod ] += nr_fii [ *it ] ;
        if ( nr_fii [ *it ] > nr_fii [ node ] ) node = *it ;
    }

    if ( !node )    {
        lant [ ++ nr_lant ].pb( nod ) ;
        pos [ nod ] = 1 ;
        w_l [ nod ] = nr_lant ;
    }   else    {
        w_l [ nod ] = w_l [ node ] ;
        pos [ nod ] = 1 + pos [ node ] ;
        lant [ w_l [ nod ] ].pb ( nod ) ;
    }

    for ( it = v [ nod ].begin() ; it != v [ nod ].end() ; ++ it )  {
        if ( *it == taticut || *it == node )    continue ;
        father [ w_l [ *it ] ] = nod ;
    }
}

void el_update ( int lant , int nod , int st , int dr , int pos , int val ) {

    if ( st == dr ) {
        aint [ lant ][ nod ] = val ;
        return ;
    }
    int mid = ( st + dr ) >> 1 ;
    if ( pos <= mid )   el_update( lant , nod << 1 , st , mid , pos , val ) ;
    else                el_update( lant , nod << 1 | 1 , mid + 1 , dr , pos , val ) ;
    aint [ lant ][ nod ] = max ( aint [ lant ][ nod << 1 ] , aint [ lant ][ nod << 1 | 1 ] ) ;
}

inline void pre_procces()
{
    int i , j ;
    for ( i = 1 ; i <= nr_lant ; ++i ) aint[ i ].resize( lant[ i ].size()*4 + 5 ) ;
    for( i = 1 ; i <= nr_lant ; ++ i )
        for( j = 0 ; j < lant[i].size() ; ++ j )
            el_update ( i , 1 , 1 , lant[ i ].size() , j + 1 , c [ lant [ i ][ j ] ] ) ;
}

int query ( int lant , int nod , int st , int dr , int a , int b )   {
    if ( a <= st && dr <= b )   return aint [ lant ][ nod ] ;
    int mid = ( st + dr ) >> 1 , lmax = 0 , rmax = 0 ;
    if ( a <= mid ) lmax = query( lant , nod << 1 , st , mid , a , b ) ;
    if ( mid <  b ) rmax = query( lant , nod << 1 | 1 , mid + 1 , dr , a , b ) ;
    return max ( lmax , rmax ) ;
}

int main()  {
    int i , x , y , tip ;
    in >> n >> q ;
    for ( i = 1 ; i <= n ; ++ i )   in >> c [ i ] ;
    for ( i = 1 ; i <  n ; ++ i )   {
        in >> x >> y ;
        v [ x ].pb ( y ) ;
        v [ y ].pb ( x ) ;
    }
    lvl [ 1 ] = 1 ;
    dfs( 1 , 0 ) ;
    pre_procces() ;
    while ( q -- )  {
        in >> tip >> x >> y ;
        if ( !tip ) {
            el_update( w_l [ x ] , 1 , 1 , lant [ w_l [ x ] ].size() , pos [ x ] , y ) ;
        }   else    {
            int sol = 0 ;
            while ( w_l [ x ] != w_l [ y ] )    {

                if ( lvl [ father [ w_l [ x ] ] ] < lvl [ father [ w_l [ y ] ] ]  )
                    swap ( x , y ) ;
                sol = max ( sol , query( w_l [ x ] , 1 , 1 , lant[ w_l [ x ] ].size() , pos [ x ] , lant [ w_l [ x ] ].size() ) ) ;
                x = father [ w_l [ x ] ] ;
            }
            sol = max ( sol , query( w_l [ x ] , 1 , 1 , lant [ w_l [ x ] ].size() , min ( pos [ y ] , pos [ x ] ) , max ( pos [ x ] , pos [ y ] ) ) ) ;
            out << sol << '\n' ;
        }
    }
}