Cod sursa(job #1759203)

Utilizator jurjstyleJurj Andrei jurjstyle Data 18 septembrie 2016 17:18:48
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include <fstream>
#include <iostream>

using namespace std ;

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

int N , M , V[100005] , Arb_int[4*100000+5] ;

void creare_arb ( int indice_arbore_curent , int st , int dr )
{
 if ( st == dr ) // am gasit frunza corespunzatoare pozitiei st din vector
    Arb_int[indice_arbore_curent] = V[st] ; // atribuim
 else
    {
     //altfel suntem la o reuniune de intervale
     int m = ( st + dr ) / 2 ; //aflam mijlocul dupa care impartim
     creare_arb ( 2 * indice_arbore_curent , st , m ) ; //apelam de fiul stang
     creare_arb ( 2 * indice_arbore_curent + 1 , m + 1 , dr ) ; //apelam de fiul drept
     Arb_int[indice_arbore_curent] = max ( Arb_int[2*indice_arbore_curent] , Arb_int[2*indice_arbore_curent+1] ) ; //alegem valoarea maxima dintre cei doi subarbori
    }
}
void update ( int i , int val , int indice_arbore_curent , int st , int dr )
{
 if ( st == dr ) //am ajuns in frunza unde inlocuim
    Arb_int[indice_arbore_curent] = val ;
 else //momentan suntem intr-un subarbore care contine frunza noastra
    {
     //mai intai reapelam de un subarbore stang/drept sa ajungem la frunza , iar la intoarcere updatam lucrurile
     int m = ( st + dr ) / 2 ;
     if ( i <= m ) //se afla in subarborele stang
        update ( i , val , 2 * indice_arbore_curent , st , m ) ;
     else //altfel este in cel drept
        update ( i , val , 2 * indice_arbore_curent + 1 , m + 1 , dr ) ;
     Arb_int[indice_arbore_curent] = max ( Arb_int[2*indice_arbore_curent] , Arb_int[2*indice_arbore_curent+1] ) ; //alegem valoare maxima din cei doi subarbori
    }
}
int query ( int i , int j , int indice_arbore_curent , int st , int dr )
{
 if ( i == st && j == dr ) //am ajuns intr-o celula in care este deja memorat raspunsul unui interval
    return Arb_int[indice_arbore_curent] ;
 int m = ( st + dr ) / 2 ;
 if ( j <= m ) //intervalul se afla total in subarborele stang
    return query ( i , j , 2 * indice_arbore_curent , st , m ) ;
 if ( m < i ) //intervalul se afla total in subarborele drept
    return query ( i , j , 2 * indice_arbore_curent + 1 , m + 1 , dr ) ;
 //daca nu s-a indeplinit niciuna pana acum ... inseamna ca ne impartim in ambii subarbori
 return max ( query ( i , m , 2 * indice_arbore_curent , st , m ) , query ( m + 1 , j , 2 * indice_arbore_curent + 1 , m + 1 , dr ) ) ;
}



int main ()
{
 f >> N >> M ;
 for ( int i = 1 ; i <= N ; ++i )
    f >> V[i] ;
 creare_arb ( 1 , 1 , N ) ;
 for ( int i = 1 ; i <= M ; ++i )
    {
     int tip , a , b ;
     f >> tip >> a >> b ;
     if ( tip == 0 )
        g << query ( a , b , 1 , 1 , N ) << "\n" ;
     else
        update ( a , b , 1 , 1 , N ) ;
    }
}