Cod sursa(job #2692366)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 2 ianuarie 2021 15:02:34
Problema Arbori de intervale Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <stdio.h>
#include <ctype.h>

#define MAXN   100000
#define MAXNOD 262144// 2^18 (nu este cu -1 deoarece avem o santinela la poz. 0)

int num[MAXN];// numerele insusi
int coresp[MAXN];// nodul care corespunde elementului i
int st[MAXNOD];
int dr[MAXNOD];
int val[MAXNOD];

FILE *fin, *fout;

static inline int max( int a, int b ){
  return a > b ? a : b;
}

static inline int fgetint(){
  int n = 0, ch;

  while( !isdigit(ch = fgetc(fin)) );
  do
    n = n * 10 + ch - '0';
  while( isdigit(ch = fgetc(fin)) );

  return n;
}

static inline void fputint( int n ){
  int i = 10;
  char out[] = "0000000000\n";

  if( n == 0 ){
    fputs("0\n", fout);
    return;
  }

  while( n ){
    out[--i] = n % 10 + '0';
    n /= 10;
  }

  fputs(out + i, fout);
}

void init( int root, int a, int b ){
  int left = 2 * root, right = 2 * root + 1;
  
  st[root] = a;
  dr[root] = b;
  
  if( a == b ){
    coresp[a] = root;
    val[root] = num[a];
  }else{
    init( left, a, (a + b)/2 );
    init( right, (a + b)/2 + 1, b );
    val[root] = max(val[left], val[right]);
  }
}

void setVal( int i, int newval ){
  int parent;

  num[i] = newval;
  val[coresp[i]] = newval;
  parent = coresp[i] / 2;
  while( parent > 0 ){// cat timp mai avem noduri de actualizat
    val[parent] = max(val[2 * parent], val[2 * parent + 1]);
    parent = parent / 2;
  }
}

/*

avem 4 cazuri:

a        b      root
[--------]  [-----------]

a           b
[-----[=====]------]
           root

        a       b
[-------[=======]-------]
          root

a                       b
[-------[=======]-------]
          root

*/

int getMax( int root, int a, int b ){
  if( st[root] > b || a > dr[root] )// daca nu se intersecteaza returnam 0
    return 0;

  if( a <= st[root] && dr[root] <= b )
    return val[root];

  return max(getMax(2 * root, a, b), getMax(2 * root + 1, a, b));
}

/*void printTree( int root, int indent ){
  int i;

  if( st[root] < dr[root] )
    printTree(2 * root, indent + 1);

  for( i = 0 ; i < indent ; i++ )
    fputs("    ", stdout);
  printf("[%d, %d] -> %d\n", st[root], dr[root], val[root]);

  if( st[root] < dr[root] )
    printTree(2 * root + 1, indent + 1);
}*/

int main(){
  fin  = fopen("arbint.in",  "r");
  fout = fopen("arbint.out", "w");

  int n, q, type, i, j, newval;

  n = fgetint();
  q = fgetint();
  for( i = 0 ; i < n ; i++ )
    num[i] = fgetint();

  // calculam starea initiala a arborelui
  init(1, 0, n - 1);// 1 = root (poz. 0 este santinela)

  // raspundem la query-uri
  for( ; q-- ; ){
    type = fgetint();

    if( type == 0 ){
      i = fgetint() - 1;
      j = fgetint() - 1;
      fputint(getMax(1, i, j));
    }else{
      i = fgetint() - 1;
      newval = fgetint();
      setVal(i, newval);
    }
  }

  fclose(fin);
  fclose(fout);
  return 0;
}