Cod sursa(job #2321995)

Utilizator vlad.ulmeanu30Ulmeanu Vlad vlad.ulmeanu30 Data 16 ianuarie 2019 22:28:29
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <bits/stdc++.h>
#define maxn 100000
#define log2m 17

using namespace std;

struct nod { int st, dr, _M; };
struct ast { int fi, se, ind; };

int v[maxn+5];
int lst[maxn+5];
nod aint[maxn*log2m+5];
vector <ast> qu;

inline void addqu ( int f, int s, int in )
{
  if ( f == s )
  {
    lst[f] = in;
    aint[in]._M = v[f];
  }
  else if ( f < s )
  {
    ast x; x.fi = f; x.se = s; x.ind = in;
    qu.push_back ( x );
  }
}
inline void setaint ( int i, int s, int d, int m ) { aint[i].st = s; aint[i].dr = d; aint[i]._M = m; }

int main ()
{
  ifstream fin ( "arbint.in" );
  ofstream fout ( "arbint.out" );

  int n, m;
  fin >> n >> m;

  int i;
  for ( i = 1; i <= n; i++ )
    fin >> v[i];

  int lo = 0, mid;
  addqu ( 1, n, 1 );
  setaint ( 1, 1, n, -1 );
  /// construire aint
  while ( lo < qu.size() )
  {
    if ( qu[lo].fi < qu[lo].se )
    {
      mid = ( qu[lo].fi + qu[lo].se ) / 2;
      setaint ( 2 * qu[lo].ind, qu[lo].fi, mid, -1 );
      addqu ( qu[lo].fi, mid, 2 * qu[lo].ind );
      if ( mid < qu[lo].se )
      {
        setaint ( 2 * qu[lo].ind + 1, mid + 1, qu[lo].se, -1 );
        addqu ( mid + 1, qu[lo].se, 2 * qu[lo].ind + 1 );
      }
    }
    lo++;
  }

  int nn;
  for ( i = 1; i <= n; i++ )
    for ( nn = lst[i]; nn > 0; nn /= 2 )
      aint[nn]._M = max ( aint[nn]._M, v[i] );

  int id, a, b, mx, oth;
  for ( ; m > 0; m-- )
  {
    fin >> id >> a >> b;
    if ( id == 0 )
    {
      mx = -1;
      while ( a <= b )
      {
        nn = lst[a];
        while ( nn / 2 > 0 && aint[nn/2].st == a && aint[nn/2].dr <= b )
          nn /= 2;

        mx = max ( mx, aint[nn]._M );
        if ( aint[nn].dr < n )
          a = lst[aint[nn].dr + 1];
        else
          a = b + 1;
      }
      fout << mx << '\n';
    }
    else
    {
      nn = lst[a];
      aint[nn]._M = b;
      for ( ; nn > 1; nn /= 2 )
      {
        oth = nn + 1; /// celalalt fiu
        if ( nn % 2 == 1 ) oth = nn - 1;
        aint[nn/2]._M = max ( aint[nn]._M, aint[oth]._M );
      }
    }
  }

  fin.close ();
  fout.close ();

  return 0;
}