Cod sursa(job #2416891)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 28 aprilie 2019 15:01:30
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100000;

int vl[MAXN + 5];
vector<int>G[MAXN + 5];
vector<int>lant[MAXN + 5];
int k;
int sz[MAXN + 5], h[MAXN + 5], cl[MAXN + 5], pos[MAXN + 5], up[MAXN + 5];

int join(int x, int y) {
  return max(x, y);
}

struct SegTree {
  int n;
  int *a;

  SegTree(int _n = 0) {
    n = _n;
    a = new int [4 * n + 5];
  }

  SegTree(int _n, vector<int>_a) {
    n = _n;
    a = new int [4 * n + 5];
    for (int i = 0; i < n; ++i)
      update(i + 1, vl[_a[i]]);
  }

  void update(int pos, int val) {
    upd(1, 1, n, pos, val);
  }

  int query(int l, int r) {
    return qry(1, 1, n, l, r);
  }

  void upd(int node, int l, int r, int pos, int val) {
    if (l == r) {
      a[node] = val;
      return ;
    }
    int mid = (l + r) / 2;
    if (pos <= mid)
      upd(2 * node, l, mid, pos, val);
    else
      upd(2 * node + 1, mid + 1, r, pos, val);
    a[node] = join(a[2 * node], a[2 * node + 1]);
  }

  int qry(int node, int l, int r, int x, int y) {
    if (l > r || y < l || r < x)
      return 0;
    if (x <= l && r <= y)
      return a[node];
    int mid = (l + r) / 2;
    return join(qry(2 * node, l, mid, x, y), qry(2 * node + 1, mid + 1, r, x, y));
  }
};

vector<SegTree>ch;

void dfs(int node, int f) {
  h[node] = h[f] + 1;
  up[node] = f;
  int w = 0;
  sz[node] = 1;
  for (auto it:G[node])
    if (it != f) {
      dfs(it, node);
      sz[node] += sz[it];
      if (sz[it] > sz[w])
        w = it;
    }
  if (w == 0) {
    w = k;
    k++;
  } else {
    w = cl[w];
  }
  cl[node] = w;
  lant[w].push_back(node);
}

void Update(int x, int y) {
  ch[cl[x]].update(pos[x], y);
}

int Query(int x, int y) {
  if (cl[x] == cl[y])
    return ch[cl[x]].query(min(pos[x], pos[y]), max(pos[x], pos[y]));
  if (h[lant[cl[x]][0]] < h[lant[cl[y]][0]])
    swap(x, y);
  return join(ch[cl[x]].query(1, pos[x]), Query(up[lant[cl[x]][0]], y));
}

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", &vl[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);
  }

  dfs(1, 0);

  for (int i = 0; i < k; ++i) {
    reverse(lant[i].begin(), lant[i].end());
    for (int j = 0; j < (int)(lant[i].size()); ++j)
      pos[lant[i][j]] = j + 1;
    SegTree aux((int)(lant[i].size()), lant[i]);
    ch.push_back(aux);
  }

  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;
}