Cod sursa(job #2738292)

Utilizator StanSiBranBranSiStan StanSiBran Data 5 aprilie 2021 17:35:10
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <bits/stdc++.h>
#define x first
#define y second
#define pii pair<int, int>
#define ll long long
 
using namespace std;
 
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const int N = 1e6 + 1;
 
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");

int n, aint[400002], m, start[100002], heavy[100002], sz[100002], poz[100002], lvl[100002], par[100002], v[100002];
vector<int>G[100002];

void update (int nod, int st, int dr, int poz, int val) {
  if (st == dr) {
    aint[nod] = val;
    return;
  }
  int mij = (st + dr) / 2;
  if (poz <= mij)
    update(2 * nod, st, mij, poz, val);
  else 
    update(2 * nod + 1, mij + 1, dr, poz, val);
  aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
  return;
}
int query (int nod, int st, int dr, int a, int b) {
  if (a <= st && dr <= b) {
    return aint[nod];
  }
  int mij = (st + dr) / 2;
  if (a <= mij && b <= mij)
    return query (2 * nod, st, mij, a, b);
  else if (a > mij && b > mij)
    return query(2 * nod + 1, mij + 1, dr, a, b);
  else 
    return max(query(2 * nod, st, mij, a, b), query(2 * nod + 1, mij + 1, dr, a, b));
} 

void dfs1 (int nod, int p) {
  sz[nod] = 1;
  lvl[nod] = lvl[p] + 1;
  par[nod] = p;
  for (auto it : G[nod]) {
    if (it != p) {
      dfs1(it, nod);
      sz[nod] += sz[it];
      if (sz[heavy[nod]] < sz[it]) 
        heavy[nod] = it;
    }
  }
}

int t;

void dfs2 (int nod, int p, int h) {
  start[nod] = h;
  poz[nod] = ++t;
  if (heavy[nod])
    dfs2(heavy[nod], nod, h);
  for (auto it : G[nod])
    if (it != heavy[nod] && it != p)
      dfs2(it, nod, it);
}

int query (int a, int b) {
  int ans = 0;
  while (start[a] != start[b]) {
    if (lvl[start[a]] > lvl[start[b]])
      swap(a, b);
    ans = max(ans, query(1, 1, n, poz[start[b]], poz[b]));
    b = par[start[b]];
  }
  if (poz[a] > poz[b])
    swap(a, b);
  ans = max(ans, query(1, 1, n, poz[a], poz[b]));
  return ans;
}

int main()
{
  fin >> n >> m;
  for (int i = 1; i <= n; i++)
    fin >> v[i];
  for (int i = 1; i < n; i++) {
    int x, y;
    fin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  dfs1(1, 0);
  dfs2(1, 0, 1);
  for (int i = 1; i <= n; i++)
    update(1, 1, n, poz[i], v[i]);
  while (m--){
    int x, y, z;
    fin >> x >> y >> z;
    if (x == 0) {
      update(1, 1, n, poz[y], z);
    }
    else 
      fout << query(y, z) << "\n";
  }
  return 0;
}