Cod sursa(job #3229674)

Utilizator IordachescuVladAlexandruIordachescu Vlad-Alexandru IordachescuVladAlexandru Data 17 mai 2024 01:49:57
Problema Arbori de intervale Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 3.44 kb
#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;
}