Cod sursa(job #2954139)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 13 decembrie 2022 12:13:22
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <fstream>
#include <vector>

using namespace std;

const int N = 1e5 + 5;

int v[N], sz[N], h_chi[N], par[N], dep[N], idx[N], top[N], aint[4 * N], t, n;
vector<int> gr[N];

void dfs_init(int nod) {
  sz[nod] = 1;
  for (auto vec : gr[nod]) {
    if (vec != par[nod]) {
      par[vec] = nod;
      dep[vec] = dep[nod] + 1;
      dfs_init(vec);
      sz[nod] += sz[vec];
      if (sz[vec] > sz[h_chi[nod]]) {
        h_chi[nod] = vec;
      }
    }
  }
}

void dfs_hf(int nod) {
  idx[nod] = ++t;
  if (h_chi[nod] != 0) {
    top[h_chi[nod]] = top[nod];
    dfs_hf(h_chi[nod]);
  }
  for (auto vec : gr[nod]) {
    if (vec != par[nod] && vec != h_chi[nod]) {
      top[vec] = vec;
      dfs_hf(vec);
    }
  }
}

void update(int p, int st, int dr, int poz, int val) {
  if (st == dr) {
    aint[p] = val;
    return;
  }
  int m = (st + dr) / 2;
  if (poz <= m) {
    update(p * 2, st, m, poz, val);
  } else {
    update(p * 2 + 1, m + 1, dr, poz, val);
  }
  aint[p] = max(aint[p * 2], aint[p * 2 + 1]);
}

int query(int p, int st, int dr, int x, int y) {
  if (st >= x && dr <= y) {
    return aint[p];
  }
  int m = (st + dr) / 2, ret = 0;
  if (x <= m) {
    ret = query(p * 2, st, m, x, y);
  }
  if (y > m) {
    ret = max(ret, query(p * 2 + 1, m + 1, dr, x, y));
  }
  return ret;
}

int query(int x, int y) {
  if (top[x] == top[y]) {
    if (dep[x] > dep[y]) {
      swap(x, y);
    }
    return query(1, 1, n, idx[x], idx[y]);
  }
  if (dep[top[x]] > dep[top[y]]) {
    swap(x, y);
  }
  return max(query(1, 1, n, idx[top[y]], idx[y]), query(x, par[top[y]]));
}

int main() {
  ifstream cin("heavypath.in");
  ofstream cout("heavypath.out");
  int q;
  cin >> n >> q;
  for (int i = 1; i <= n; ++i) {
    cin >> v[i];
  }
  for (int i = 1; i <= n - 1; ++i) {
    int x, y;
    cin >> x >> y;
    gr[x].push_back(y);
    gr[y].push_back(x);
  }
  dfs_init(1);
  top[1] = 1;
  dfs_hf(1);
  for (int i = 1; i <= n; ++i) {
    update(1, 1, n, idx[i], v[i]);
  }
  while (q--) {
    int op, x, y;
    cin >> op >> x >> y;
    if (op == 0) {
      update(1, 1, n, idx[x], y);
    } else {
      cout << query(x, y) << "\n";
    }
  }
  cin.close();
  cout.close();
  return 0;
}