Cod sursa(job #2817200)

Utilizator victorzarzuZarzu Victor victorzarzu Data 13 decembrie 2021 10:28:27
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.53 kb
#include <bits/stdc++.h>
#define n_max 100001

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

void read()
{
  f>>n>>m;
  for(int i = 1;i <= n;++i)
    f>>vals[i]; 
  int x, y;
  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 par)
{
  level[node] = level[par] + 1;
  size[node] = 1;
  parent[node] = par;

  int maximum = 0;
  for(int children : graf[node])
    if(children != par)
    {
      dfs(children, node);
      size[node] += size[children];

      if(maximum < size[children])
        heavy[node] = children, maximum = size[children];
    }
}

void heavypath(int node, int superior)
{
  seq[node] = superior;
  position[node] = ++pos;

  if(heavy[node])
    heavypath(heavy[node], superior);
  
  for(int children : graf[node])
    if(children != parent[node] && children != heavy[node])
      heavypath(children, children);
}

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

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

int query_all(int x, int y)
{
  int result = 0;

  while(seq[x] != seq[y])
  {
    if(level[seq[x]] < level[seq[y]])
      swap(x, y);

    result = max(result, query(1, 1, n, position[seq[x]], position[x])); 
    x = parent[seq[x]];
  }
  if(level[x] < level[y])
    swap(x, y);
  result = max(result, query(1, 1, n, position[y], position[x]));

  return result;
}

void solve()
{
  dfs(1, 0);
  heavypath(1, 1);

  for(int i = 1;i <= n;++i)
    update(1, 1, n, position[i], vals[i]);

  int x, y, z;
  for(int i = 1;i <= m;++i)
  {
    f>>x>>y>>z;
    if(!x)
      update(1, 1, n, position[y], z);
    else
      g<<query_all(y, z)<<'\n';
  }
}

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