Cod sursa(job #2849956)

Utilizator Asgari_ArminArmin Asgari Asgari_Armin Data 16 februarie 2022 00:19:52
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.6 kb
#include <bits//stdc++.h>

using namespace std;

ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");

const int NMAX = 1e5;

int posCurr, n, m;
int v[NMAX + 2];
int aint[NMAX + 2];
int depth[NMAX + 2];
int parent[NMAX + 2];
int heavy[NMAX + 2];
int pos[NMAX + 2];
int head[NMAX + 2];
int viz[NMAX + 2];
vector <int> g[NMAX + 2];

int dfs (int node) {
  int sz = 1, maxSize = 0;
  viz[node] = 1;

  for (int next : g[node]) {
    if (!viz[next]) {
      depth[next] = 1 + depth[node];
      parent[next] = node;

      int csz = dfs(next);
      sz += csz;

      if (maxSize < csz) {
        maxSize = csz;
        heavy[node] = next;
      }
    }
  }
  return sz;
}

void decompuse (int node, int sef) {
  head[node] = sef;
  pos[node] = ++posCurr;
  viz[node] = 1;

  if (!viz[heavy[node]] && heavy[node] != 0)
    decompuse(heavy[node], sef);

  for (int next : g[node])
    if (!viz[next] && heavy[node] != next)
      decompuse(next, next);
}

void update (int node, int from, int to, int pos, int x) {
  if (from == to) {
    aint[node] = x;
    return ;
  }

  int mid = (from + to) >> 1;
  if (x <= mid)
    update (2 * node, from, mid, pos, x);
  else
    update (2 * node + 1, mid + 1, to, pos, x);
  aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}

int query (int node, int from, int to, int x, int y) {
  if (from == x && y == to)
    return aint[node];

  int mid = (from + to) >> 1;

  if (x > mid)
    return query (2 * node + 1, mid + 1, to, x, y);
  if (y <= mid)
    return query (2 * node, from, mid, x, y);
  return max(query(2 * node, from, mid, x, mid), query(2 * node + 1, mid + 1, to, mid + 1, y));
}

int value (int a, int b) {
  if (a > b) swap(a, b);
  return query (1, 1, n, a, b);
}

int solve (int a, int b) {
  int max1 = 0;
  for (; head[a] != head[b]; b = parent[head[b]]) {
    if (depth[head[a]] > depth[head[b]])
      swap(a, b);

    max1 = max(max1, value(pos[head[b]], pos[b]));
  }
  if (depth[a] > depth[b])
    swap(a, b);
  max1 = max(max1, value(pos[a], pos[b]));
  return max1;
}

int main() {
  int i, tip, x, y;

  fin >> n >> m;

  for (i = 1; i <= n; ++i)
    fin >> v[i];

  for (i = 1; i < n; ++i) {
    fin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }

  dfs(1);
  for (i = 1; i <= n; ++i)
    viz[i] = 0;
  decompuse(1, 1);

  for (i = 1; i <= n; ++i)
    update(1, 1, n, i, v[i]);

  while (m--) {
    fin >> tip >> x >> y;
    if (tip == 0)
      update(1, 1, n, x, y);
    else
      fout << solve(x, y) << "\n";
  }

  return 0;
}