Cod sursa(job #2767991)

Utilizator grecu_tudorGrecu Tudor grecu_tudor Data 8 august 2021 21:17:31
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.53 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#define pb push_back

using namespace std;

ifstream fin( "heavypath.in" );
ofstream fout( "heavypath.out" );

const int MAXN = 100005;

int aint[4 * MAXN], n;
int init_val[MAXN], fth[MAXN], dim[MAXN], heavySon[MAXN], head[MAXN], level[MAXN]; 
int ind[MAXN], vertex[MAXN], sz;
bool used[MAXN];
vector<int> T[MAXN];

void predfs( int u ) {
  int mx = 0;
  dim[u] = 1; 
  used[u] = true;
  for ( int v : T[u] ) {
    if ( !used[v] ) { 
      level[v] = level[u] + 1;
	  predfs( v );
	  fth[v] = u;
	  dim[u] += dim[v];
	  if ( dim[v] > mx ) {
        mx = dim[v];
		heavySon[u] = v;
	  }
    }
  }
}
void dfsPaths( int u, int this_head ) {
  used[u] = true;
  ind[u] = sz;
  head[u] = this_head;
  vertex[sz++] = u;
  if ( !heavySon[u] ) {
    return; 
  }
  dfsPaths( heavySon[u], this_head );
  for ( int v : T[u] ) {
	if ( !used[v] ) {
	  dfsPaths( v, v );
	}
  }
}
void update( int node, int l, int r, int pos, int val ) {
  if ( l == r ) {
    aint[node] = val;
    return;
  }
  int mid = (l + r) / 2;
  if ( pos <= mid ) {
	update( 2 * node, l, mid, pos, val );
  } else {
	update( 2 * node + 1, mid + 1, r, pos, val );
  }
  aint[node] = max( aint[2 * node], aint[2 * node + 1] );
}
int query( int node, int l, int r, int x, int y ) {
  int res = 0;
  if ( x <= l && r <= y ) {
	return aint[node];
  }
  int mid = (l + r) / 2;
  if ( x <= mid ) {
	res = max( res, query( 2 * node, l, mid, x, y ) );
  }
  if ( y > mid ) {
	res = max( res, query( 2 * node + 1, mid + 1, r, x, y ) );
  }
  return res;
}
inline int realQuery( int u, int v ) {
  int res = 0;
  while ( head[u] != head[v] ) {
    if ( level[head[u]] < level[head[v]] ) {
	  swap( u, v );
    }
    res = max( res, query( 1, 1, n, ind[head[u]], ind[u] ) );
    u = fth[head[u]]; 
  }
  if ( level[u] > level[v] ) {
    swap( u, v );
  }
  res = max( res, query( 1, 1, n, ind[u], ind[v] ) );
  return res;
}
inline void realUpdate( int u, int val ) {
  update( 1, 1, n, ind[u], val );
}

int main() {
  int t, x, y, tp;

  fin >> n >> t;
  for ( int i = 1; i <= n; ++i ) {
    fin >> init_val[i];   
  }
  for ( int i = 1; i < n; ++i ) {
	fin >> x >> y;
    T[x].pb( y );
	T[y].pb( x );
  }
  sz = 1;
  predfs( 1 );
  for ( int i = 1; i <= n; ++i ) used[i] = false;
  dfsPaths( 1, 1 );
  for ( int i = 1; i <= n; ++i ) {
	update( 1, 1, n, ind[i], init_val[i] );
  }
  while ( t-- ) {
	fin >> tp >> x >> y;
	if ( tp == 0 ) {
	  realUpdate( x, y );
	} else {
	  fout << realQuery( x, y ) << "\n";
	}
  }
  fin.close();
  fout.close();
  return 0;
}