Cod sursa(job #2257391)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 10 octombrie 2018 00:00:56
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100000;

vector<int>G[MAXN + 5];
int sz[MAXN + 5];
int ind[MAXN + 5], nr[MAXN + 5];
vector<int>lant[MAXN + 5];
int vv[MAXN + 5];
int h[MAXN + 5];
int ff[MAXN + 5];
int nl;
int k1;

struct SegTree {
  int n;
  int* a;

  SegTree(int x) {
    n = x;
    a = new int [4 * n + 5];
    memset(a, 0, sizeof(a));
  }

  void build(vector<int>v) {
    for (int i = 1; i <= n; ++i)
      update(i, v[i - 1]);
  }

  void update(int poz, int val) {
    u(1, 1, n, poz, val);
  }

  int query(int st, int dr) {
    return q(1, 1, n, st, dr);
  }

  void u(int node, int st, int dr, int poz, int val) {
    if (st == dr) {
      a[node] = val;
      return ;
    }
    int med = (st + dr) >> 1;
    if (med >= poz)
      u(2 * node, st, med, poz, val);
    else
      u(2 * node + 1, med + 1, dr, poz, val);
    a[node] = max(a[2 * node], a[2 * node + 1]);
  }

  int q(int node, int st, int dr, int l, int r) {
    if (l <= st && dr <= r)
      return a[node];
    int ans = 0;
    int med = (st + dr >> 1);
    if (l <= med)
      ans = q(2 * node, st, med, l, r);
    if (r > med)
      ans = max(ans, q(2 * node + 1, med + 1, dr, l, r));
    return ans;
  }
};

void prec(int node, int f) {
  sz[node] = 1;
  h[node] = 1 + h[f];
  ff[node] = f;
  for (auto it:G[node])
    if (it != f) {
      prec(it, node);
      sz[node] += sz[it];
    }
}

void dfs(int node, int f, int k) {
  nl = max(nl, k);
  ind[node] = k;
  lant[k].push_back(node);
  nr[node] = lant[k].size();
  int x = 0;
  for (auto it:G[node])
    if (it != f && sz[x] < sz[it])
      x = it;
  if (x)
    dfs(x, node, k);
  for (auto it:G[node])
    if (it != f && it != x) {
      k1++;
      dfs(it, node, k1);
    }
}

vector<SegTree>hp;

void update(int x, int y) {
  hp[ind[x]].update(nr[x], y);
}

int query(int x, int y) {
  if (ind[x] == ind[y]) {
    if (h[x] > h[y])
      swap(x, y);
    return hp[ind[x]].query(nr[x], nr[y]);
  }
  if (h[lant[ind[x]][0]] < h[lant[ind[y]][0]])
    swap(x, y);
  return max(query(ff[lant[ind[x]][0]], y), hp[ind[x]].query(1, nr[x]));
}

int main() {
  freopen("heavypath.in", "r", stdin);
  freopen("heavypath.out", "w", stdout);

  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &vv[i]);
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }

  prec(1, 0);
  dfs(1, 0, 0);

  for (int i = 0; i <= nl; ++i) {
    SegTree a(lant[i].size());
    vector<int>aux;
    for (auto it:lant[i])
      aux.push_back(vv[it]);
    a.build(aux);
    hp.push_back(a);
  }

  for (int i = 1; i <= m; ++i) {
    int t, x, y;
    scanf("%d%d%d", &t, &x, &y);
    if (t == 0)
      update(x, y);
    else
      printf("%d\n", query(x, y));
  }

  return 0;
}