Cod sursa(job #2818376)

Utilizator Asgari_ArminArmin Asgari Asgari_Armin Data 15 decembrie 2021 22:43:00
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5;

vector <int> parent;
vector <int> head;
vector <int> heavy;
vector <int> depth;
vector <int> pos;
vector <int> g[NMAX + 2];

int v[NMAX + 2];
int aint[4 * NMAX + 2];
int poscurr, n;

int dfs( int node ) {
  int sz = 1;
  int max_size = 0;
  for( int next : g[node] ) {
    if( next != parent[node] ) {
      parent[next] = node;
      depth[next] = 1 + depth[node];

      int csz = dfs(next);
      sz += csz;
      if( max_size < csz ) {
        max_size = csz;
        heavy[node] = next;
      }
    }
  }
  return sz;
}

void decompuse( int node, int sef ){
  head[node] = sef;
  pos[node] = ++poscurr;

  if( heavy[node] != -1 )
    decompuse(heavy[node], sef);

  for( int next : g[node] ) {
    if( next != parent[node] && heavy[node] != next )
      decompuse(next, next);
  }
}

void init() {
  parent = vector <int> (1 + n);
  head = vector <int> (1 + n);
  heavy = vector <int> (1 + n, -1);
  depth = vector <int> (1 + n);
  pos = vector <int> (1 + n);

  dfs(1);
  decompuse(1, 1);
}

void update( int node, int from, int to, int pos, int x ) {
  if( from == to ) {
    aint[node] = x;
    return ;
  }

  int mid = (from + to) >> 1;
  if( pos <= mid )
    update(2 * node, from, mid, pos, x);
  else
    update(2 * node + 1, mid + 1, to, pos, x);
  aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}

int query( int node, int from, int to, int x, int y ) {
  if( from == x && y == to )
    return aint[node];

  int mid = (from + to) >> 1;

  if( y <= mid )
    return query(2 * node, from, mid, x, y);
  else if( x > mid )
    return query(2 * node + 1, mid + 1, to, x, y);
  return max(query(2 * node, from, mid, x, mid), query(2 * node + 1, mid + 1, to, mid + 1, y));
}

int plm( int a, int b ){
  return query(1, 1, n, min(a, b), max(a, b));
}

int solve( int a, int b ) {
  int ans = 0;
  for( ; head[a] != head[b]; b = parent[head[b]] ) {
    if( depth[head[a]] > depth[head[b]] )
      swap(a, b);

    ans = max(ans, plm(pos[head[b]], pos[b]));
  }

  if( depth[a] > depth[b] )
    swap(a, b);

  ans = max(ans, plm(pos[a], pos[b]));
  return ans;
}

int main() {
  int m, i, c, a, b;
  fin >> n >> m;

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

  for( i = 0; i < n - 1; ++i ) {
    fin >> a >> b;
    g[a].push_back(b);
    g[b].push_back(a);
  }

  init();
  for( i = 1; i <= n; ++i )
    update(1, 1, n, pos[i], v[i]);

  while( m-- ) {
    fin >> c >> a >> b;
    if( c == 0 )
      update(1, 1, n, pos[a], b);
    else
      fout << plm(a, b) << "\n";
  }
  return 0;
}