Cod sursa(job #2806301)

Utilizator victorzarzuZarzu Victor victorzarzu Data 22 noiembrie 2021 15:00:00
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.49 kb
#include <bits/stdc++.h>
#define n_max 100000 

using namespace std;
ifstream f("heavypath.in");
ofstream g("heavtpath.out");
int n, m, pos, heavy[n_max + 5], level[n_max + 5], t[n_max + 5], position[n_max + 5], seq[n_max + 5], val[n_max + 5], size[n_max + 5], arb[4 * n_max + 5];
vector<int> graf[n_max + 5];

void read()
{
  f>>n>>m;
  int x, y;
  for(int i = 1;i <= n;++i)
    f>>val[i];
  for(int i = 1;i < n;++i)
    f>>x>>y, graf[x].push_back(y), graf[y].push_back(x);
}

void dfs(int node, int parent)
{
  level[node] = level[parent] + 1;
  t[node] = parent;
  size[node] = 1;
  int maximum = 0;
  for(auto it : graf[node])
    if(it != parent)
      {
        dfs(it, node);
        size[node] += size[it];
        if(maximum < size[it])
          maximum = size[it], heavy[node] = it;
      }
}

void decompose(int node, int superior)
{
  seq[node] = superior, position[node] = ++pos;
  if(heavy[node])
    decompose(heavy[node], superior);
  for(auto it : graf[node])
    if(it != t[node] && it != heavy[node])
      decompose(it, it);
}

void update(int node, int left, int right, int position, int value)
{
  if(position < left || position > right)
    return;
  if(left == right)
    {
      arb[node] = value;
      return;
    }
  
  int mid = (left + right) >> 1;
  update(2 * node, left, mid, position, value);
  update(2 * node + 1, mid + 1, right, position, value);
  arb[node] = max(arb[2 * node], arb[2 * node + 1]);
}

int query(int node, int left, int right, int st, int fin)
{
  if(left > right || st > right || fin < left)
    return 0;
  if(st <= left && right <= fin)
    return arb[node];
  
  int mid = (left + right) >> 1;
  return max(query(2 * node, left, mid, st, fin), query(2 * node + 1, mid + 1, right, st, fin));

}

int query_all(int x, int y)
{
  int rez = 0;
  while(seq[x] != seq[y])
  {
    if(level[seq[x]] < level[seq[y]])
      swap(x, y);
    rez = max(rez, query(1, 1, n, position[seq[x]], position[x]));
    x = t[seq[x]];
  }
  if(level[x] < level[y])
    swap(x, y);
  rez = max(rez, query(1, 1, n, position[y], position[x]));
  return rez;
}

void solve()
{
  dfs(1, 0);
  decompose(1, 1);
  for(int i = 1;i <= n;++i)
    update(1, 1, n, position[i], val[i]);
  int t, x, y;
  for(int i = 1;i <= m;++i)
    {
      f>>t>>x>>y;
      if(!t)
        update(1, 1, n, position[x], y);
      else
        g<<query_all(x, y)<<'\n';
    }
}

int main()
{
  read();
  solve();
  return 0;
}