Cod sursa(job #2647011)

Utilizator lucametehauDart Monkey lucametehau Data 2 septembrie 2020 17:50:25
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin ("heavypath.in");
ofstream cout ("heavypath.out");

int n, m, tip, x, y;
int poz_cnt;

int v[100005];
int sz[100005], t[100005], heavy[100005];
int top[100005], h[100005], poz[100005];
int aint[400005];
vector <int> g[100005];

void dfs(int nod, int tata = 0) {
  sz[nod] = 1;
  t[nod] = tata;
  h[nod] = h[tata] + 1;
  int mx = 0;
  for(auto &fiu : g[nod]) {
    if(fiu != tata) {
      dfs(fiu, nod);
      sz[nod] += sz[fiu];
      if(sz[fiu] > mx)
        mx = sz[fiu], heavy[nod] = fiu;
    }
  }
}

void build(int nod, int par) {
  top[nod] = par, poz[nod] = ++poz_cnt;
  if(heavy[nod])
    build(heavy[nod], par);
  for(auto &fiu : g[nod]) {
    if(fiu != t[nod] && fiu != heavy[nod])
      build(fiu, fiu);
  }
}

void update(int nod, int st, int dr, int ind, int val) {
  if(ind < st || dr < ind)
    return;
  if(st == dr) {
    aint[nod] += val;
    return;
  }
  int mid = (st + dr) >> 1;
  update((nod << 1), st, mid, ind, val);
  update((nod << 1) | 1, mid + 1, dr, ind, val);
  aint[nod] = max(aint[(nod << 1)], aint[(nod << 1) | 1]);
}

int query(int nod, int st, int dr, int l, int r) {
  if(r < st || dr < l || st > dr)
    return 0;
  if(l <= st && dr <= r)
    return aint[nod];
  int mid = (st + dr) >> 1;
  return max(query((nod << 1), st, mid, l, r), query((nod << 1) | 1, mid + 1, dr, l, r));
}

int solve(int x, int y) {
  int ans = 0;
  while(top[x] != top[y]) {
    if(h[top[x]] > h[top[y]])
      swap(x, y);
    ans = max(ans, query(1, 1, n, poz[top[y]], poz[y]));
    y = t[top[y]];
  }
  if(h[x] > h[y])
    swap(x, y);
  ans = max(ans, query(1, 1, n, poz[x], poz[y]));
  return ans;
}

int main() {
  cin >> n >> m;
  for(int i = 1; i <= n; i++)
    cin >> v[i];
  for(int i = 1; i < n; i++) {
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  dfs(1);
  build(1, 1);
  for(int i = 1; i <= n; i++)
    update(1, 1, n, poz[i], v[i]);
  for(; m; m--) {
    cin >> tip >> x >> y;
    if(tip == 0) {
      update(1, 1, n, poz[x], y - v[x]);
      v[x] = y;
    } else {
      cout << solve(x, y) << '\n';
    }
  }
  return 0;
}