Cod sursa(job #2989767)

Utilizator vladburacBurac Vlad vladburac Data 6 martie 2023 23:03:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.93 kb
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e5;

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

int val[NMAX+1];
vector <int> edges[NMAX+1];
int sz[NMAX+1];
int heavyChild[NMAX+1];
int parent[NMAX+1], depth[NMAX+1];

int n;
int aint[2*NMAX+1];
void update( int node, int left, int right, int poz, int val ) {
  int mid, leftSon, rightSon;
  if( left == right ) {
    aint[node] = val;
    return;
  }
  mid = ( left + right ) / 2;
  leftSon = node + 1;
  rightSon = node + 2 * ( mid - left + 1 );
  if( poz <= mid )
    update( leftSon, left, mid, poz, val );
  else
    update( rightSon, mid + 1, right, poz, val );
  aint[node] = max( aint[leftSon], aint[rightSon] );
}

int query( int node, int left, int right, int qleft, int qright ) {
  int mid, leftSon, rightSon;
  if( left >= qleft && right <= qright ) {
    return aint[node];
  }
  if( right < qleft || left > qright ) {
    return 0;
  }
  mid = ( left + right ) / 2;
  leftSon = node + 1;
  rightSon = node + 2 * ( mid - left + 1 );
  int ans = 0;
  if( qleft <= mid )
    ans = max( ans, query( leftSon, left, mid, qleft, qright ) );
  if( qright >= mid + 1 )
    ans = max( ans, query( rightSon, mid + 1, right, qleft, qright ) );
  return ans;
}

void dfs( int node, int par, int lvl ) {
  sz[node] = 1;
  parent[node] = par;
  depth[node] = lvl;
  int maxi = -1;
  for( auto vec: edges[node] ) {
    if( vec != par ) {
      dfs( vec, node, lvl + 1 );
      sz[node] += sz[vec];
      if( sz[vec] > maxi ) {
        maxi = sz[vec];
        heavyChild[node] = vec;
      }
    }
  }
}

int label[NMAX+1];
int head[NMAX+1];
int t = 0;

void dfs_labels( int node, int chainHead ) {
  label[node] = t++;
  head[node] = chainHead;
  if( heavyChild[node] != -1 ) {
    dfs_labels( heavyChild[node], chainHead );
  }
  for( auto vec: edges[node] ) {
    if( vec != parent[node] && vec != heavyChild[node] )
      dfs_labels( vec, vec );
  }
}

int heavy_query( int a, int b ) {
  int ans = 0;
  while( head[a] != head[b] ) {
    if( depth[head[a]] < depth[head[b]] )
      swap( a, b );
    ans = max( ans, query( 0, 0, n - 1, label[head[a]], label[a] ) );
    a = parent[head[a]];
  }
  ans = max( ans, query( 0, 0, n - 1, min( label[a], label[b] ), max( label[a], label[b] ) ) );
  return ans;
}

int main() {
  int q, i, a, b, op, x, y;
  fin >> n >> q;
  for( i = 0; i < n; i++ ) {
    fin >> val[i];
    heavyChild[i] = -1;
  }
  for( i = 0; i < n - 1; i++ ) {
    fin >> a >> b;
    a--, b--;
    edges[a].push_back( b );
    edges[b].push_back( a );
  }
  dfs( 0, -1, 0 );
  dfs_labels( 0, 0 );
  for( i = 0; i < n; i++ )
    update( 0, 0, n - 1, label[i], val[i] );
  for( i = 0; i < q; i++ ) {
    fin >> op >> x >> y;
    if( op == 0 )
      update( 0, 0, n - 1, label[x-1], y );
    else {
      fout << heavy_query( x - 1, y - 1 ) << "\n";
    }
  }
  return 0;
}