Cod sursa(job #2051892)

Utilizator b0gd4nBogdan b0gd4n Data 29 octombrie 2017 17:59:43
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
#include <algorithm>
#include <stdio.h>

#define MAXN 100000

int Arb[1 << 18]; //Alegem k astfel incat 2^k>=2*N-1.

inline
void Update(
  int nod, //Nod curent.
  int st,  //Stanga.
  int dr,  //Dreapta.
  int poz, //Pozitia de inserare a noului element.
  int val  //Valoarea cu care va fi actualizat elementul de pe poz.
  )
{
  //Interval elementar.
  if ( st == poz && poz == dr )
  {
    Arb[ nod ] = val;
    return; //Ma opresc deoarece nu mai am fii si nu mai este necesar sa actualizez maximul dintre ei.
  }

  //Calculez mijlocul.
  int m = (st + dr) >> 1;

  //Daca pozitia se afla in stanga mijlocului.
  if ( poz <= m ) Update((nod << 1), st, m, poz, val); //Fiu stanga.
  else Update((nod << 1) + 1, m + 1, dr, poz, val); //Fiu dreapta.

  //Actaulizez maximul dintre cei doi fii.
  Arb[ nod ] = std::max(Arb[ (nod << 1) ], Arb[ (nod << 1) + 1 ]);
}

/*
* Returneaza maximul din intervalul [a,b].
*/
inline
int Query(
    int nod, //Nodul curent.
    int st,  //Stanga.
    int dr,  //Dreapta.
    int a,   //Capatul din stanga al intervalului cautat.
    int b    //Capatul din dreapta al intervalului cautat.
  )
{
  //Intervalul [st,dr] este inclus in [a,b].
  if (a <= st && dr <= b)
  {
    return Arb[ nod ];
  }

  //Initial sunt 0.
  int Qst = 0; //Query pentru fiul stang.
  int Qdr = 0; //Query pentru fiul drept.

  //Calculez mijlocul.
  int m = (st + dr) >> 1;

  //Daca intervalul cautat contine valori in fiul stang.
  if (a <= m)
    Qst = Query((nod << 1), st, m, a, b);

  //Daca intervalul cautat contine valori in fiul drept.
  if (b > m)
    Qdr = Query((nod << 1) + 1, m + 1, dr, a, b);

  return std::max(Qst, Qdr);
}

int main()
{
  int N, M;
  int cer, a, b;

  FILE * f = fopen("arbint.in", "r");
  FILE * g = fopen("arbint.out", "w");

  if (f && g)
  {
    fscanf(f, "%d %d", &N, &M);

    for (int i = 1, x; i <= N; i++)
    {
      fscanf(f, "%d", &x);
      Update(1, 1, N, i, x);
    }

    for (int i = 1; i <= M; i++)
    {
      fscanf(f, "%d %d %d", &cer, &a, &b);

      if (cer)
        Update(1, 1, N, a, b);
      else
        fprintf(g, "%d\n", Query(1, 1, N, a, b) );
    }


    fclose(f);
    fclose(g);
  }

  return 0;
}