Cod sursa(job #2692021)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 31 decembrie 2020 10:18:07
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

const int NMAX = 100000;

int n, m, aint_poz;
int val[NMAX + 5], h[NMAX + 5], aint[2 * NMAX + 5];
int path_first[NMAX + 5], path_dad[NMAX + 5], path_poz[NMAX + 5];
vector<int> v[NMAX + 5];

int dfs(int nod, int dad) {
  int cnt = 1, maxc = 0, heaviest = 0;
  h[nod] = h[dad] + 1;

  for(int i = 0; i < v[nod].size(); i++)
    if(v[nod][i] != dad) {
      int crt = dfs(v[nod][i], nod);
      if(crt > maxc) {
        heaviest = i;
        maxc = crt;
      }
      cnt += crt;
    }

  if(heaviest) swap(v[nod][0], v[nod][heaviest]);
  return cnt;
}

void decomposition(int nod, int dad, bool first) {
  aint[aint_poz] = val[nod];
  path_poz[nod] = aint_poz++;

  path_first[nod] = first ? nod : path_first[dad];
  path_dad[nod] = first ? dad : path_dad[dad];

  for(int i = 0; i < v[nod].size(); i++)
    if(v[nod][i] != dad) decomposition(v[nod][i], nod, i);
}

void build() {
  for(int i = n - 1; i; i--)
    aint[i] = max(aint[i << 1], aint[i << 1 | 1]);
}

void update(int nod, int val) {
  aint[path_poz[nod]] = val;
  for(int poz = path_poz[nod] >> 1; poz; poz >>= 1)
    aint[poz] = max(aint[poz << 1], aint[poz << 1 | 1]);
}

int query(int nod1, int nod2) {
  int ans = 0;
  if(path_poz[nod1] > path_poz[nod2]) swap(nod1, nod2);

  for(int st = path_poz[nod1], dr = path_poz[nod2]; st <= dr; st >>= 1, dr >>= 1) {
    if(st & 1)
      ans = max(ans, aint[st++]);
    if(!(dr & 1))
      ans = max(ans, aint[dr--]);
  }

  return ans;
}

int qquery(int nod1, int nod2) {
  int ans = 0;

  while(path_first[nod1] != path_first[nod2]) {
    if(h[path_first[nod1]] < h[path_first[nod2]]) swap(nod1, nod2);
    ans = max(ans, query(path_first[nod1], nod1));
    nod1 = path_dad[nod1];
  }
  ans = max(ans, query(nod1, nod2));

  return ans;
}

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

  scanf("%d %d", &n, &m);
  for(int i = 1; i <= n; i++) scanf("%d", &val[i]);
  for(int i = 1; i < n; i++) {
    scanf("%d %d", &a, &b);
    v[a].push_back(b);
    v[b].push_back(a);
  }

  dfs(1, 0);
  aint_poz = n;
  decomposition(1, 0, true);

  build();
  while(m--) {
    scanf("%d %d %d", &t, &a, &b);
    if(t)
      printf("%d\n", qquery(a, b));
    else
      update(a, b);
  }

  return 0;
}