#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define FILE_IN "arbint.in"
#define FILE_OUT "arbint.out"
// Arborele este unul binar pt pozitiile din vector ( La stanga se afla pozitiile mai mici decat radacine, la dreapta mai mari )
typedef struct nod
{
struct nod *left, *right;
uint32_t ll, lr, val; // limLeft, limRight, max in interv[ll, lr]
} NOD;
uint32_t maxim ( uint32_t e1, uint32_t e2 )
{
if ( e1 > e2 )
return e1;
return e2;
}
NOD *new_node( uint32_t lleft, uint32_t lright )
{
NOD *nod = malloc ( sizeof ( NOD ) * 1 );
if ( nod == NULL )
{
perror ( "Eroare la alocare\n" );
exit ( -3 );
}
// default
nod->left = NULL;
nod->right = NULL;
nod->val = 0;
nod->ll = lleft;
nod->lr = lright;
return nod;
}
// alternativ: // creez odata arborele, apoi updatez in citire (?)
// NOD *create ( uint32_t poz, uint32_t lleft, uint32_t lright ) // pt a nu apela fct update(), compar direct valoarea fiecarui nod cu val ce tb introdusa
NOD *create ( uint32_t lleft, uint32_t lright )
{
// printf ( "%u | %u\n", lleft, lright );
NOD *nod = new_node ( lleft, lright );
if ( lleft != lright )
{
/*
nod->val = val;
}
else
{
*/
uint32_t mid = lleft + ( lright - lleft ) / 2;
nod->left = create ( lleft, mid );
nod->right = create ( mid + 1, lright );
// nod->val = maxim ( nod->left->val, nod->right->val );
}
return nod;
}
void update ( NOD *arbore, uint32_t poz, uint32_t val )
{
// printf ( "%u | %u | %u | %u\n", arbore->ll, arbore->lr, poz, val );
if ( arbore->ll == arbore->lr )
{
arbore->val = val;
return;
}
uint32_t mid = arbore->ll + ( arbore->lr - arbore->ll ) / 2;
if ( poz <= mid )
update ( arbore->left, poz, val );
else
update ( arbore->right, poz, val );
arbore->val = maxim ( arbore->left->val, arbore->right->val );
}
uint32_t search ( NOD *arbore, uint32_t a, uint32_t b )
{
// printf ( "%u | %u | %u | %u\n", arbore->ll, arbore->lr, a, b );
uint32_t m1, m2;
if ( arbore->ll == a && arbore->lr == b )
return arbore->val;
uint32_t mid = arbore->ll + ( arbore->lr - arbore->ll ) / 2;
if ( mid < a )
return search ( arbore->right, a, b );
if ( b <= mid )
return search ( arbore->left, a, b );
m1 = search ( arbore->left, a, mid );
m2 = search ( arbore->right, mid + 1, b );
return maxim ( m1, m2 );
}
int main ( void )
{
FILE *fin, *fout;
fin = fopen ( FILE_IN, "r" );
fout = fopen ( FILE_OUT, "w" );
if ( fin == NULL || fout == NULL )
{
perror ( "Eroare la deschidere fisiere\n" );
exit ( -1 );
}
uint32_t n, m, x, a, b;
uint8_t opt;
// tb initializat arborele general, apoi introduse alementele in el
fscanf ( fin, "%u %u\n", &n, &m );
NOD *arbore = create ( 1, n );
for ( uint32_t i = 0; i < n; i++ )
{
fscanf ( fin, "%u", &x );
update ( arbore, i + 1, x );
}
// printf ( "READING INIT FINISH\n" );
for ( uint32_t i = 0; i < m; i++ )
{
fscanf ( fin, "%hhu %u %u\n", &opt, &a, &b );
// printf ( "\n\t%hhu | %u | %u\n\n", opt, a, b );
if ( opt )
{
update ( arbore, a, b );
}
else
{
uint32_t rez = search ( arbore, a, b );
// printf ( "%u\n", rez );
fprintf ( fout, "%u\n", rez );
}
}
if ( ( fclose ( fin ) ) != 0 || ( fclose ( fout ) ) != 0 )
{
perror ( "Eroare la inchidere fisiere\n" );
exit ( -2 );
}
return 0;
}