Cod sursa(job #3151177)

Utilizator victorzarzuZarzu Victor victorzarzu Data 19 septembrie 2023 23:39:59
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.47 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
#define oo 0x3f3f3f3f
#define n_max 100001

ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n, m, pos;
int vals[n_max], seq[n_max], level[n_max], heavy[n_max], parent[n_max], arb[4 * n_max], position[n_max], size[n_max];
vector<int> graph[n_max];

void read() {
  f>>n>>m;
  for(int i = 1;i <= n;++i) {
    f>>vals[i];
  }
  int x, y;
  for(int i = 1;i < n;++i) {
    f>>x>>y, graph[x].push_back(y), graph[y].push_back(x);
  }
}

void dfs(int node, int par) {
  parent[node] = par;
  level[node] = level[par] + 1;
  size[node] = 1;

  int maximum = 0;
  for(const auto& ngh : graph[node]) {
    if(ngh != par) {
      dfs(ngh, node);
      size[node] += size[ngh];

      if(size[ngh] > maximum) {
        maximum = size[ngh];
        heavy[node] = ngh;
      }
    }
  }
}

void decompose(int node, int superior) {
  position[node] = ++pos;
  seq[node] = superior;

  if(heavy[node]) {
    decompose(heavy[node], superior);
  }

  for(const auto& ngh : graph[node]) {
    if(heavy[node] != ngh && ngh != parent[node]) {
      decompose(ngh, ngh);
    }
  }
}

void update(int node, int left, int right, int pos, int val) {
  if(left > right || left > pos || right < pos) {
    return;
  }

  if(left == right) {
    arb[node] = val;
    return;
  }

  int mid = (left + right) >> 1;
  update(2 * node, left, mid, pos, val);
  update(2 * node + 1, mid + 1, right, pos, val);
  arb[node] = max(arb[2 * node], arb[2 * node + 1]);
}

int query(int node, int left, int right, int a, int b) {
  if(left > right || right < a || b < left) {
    return 0;
  }

  if(left >= a && right <= b) {
    return arb[node];
  }

  int mid = (left + right) >> 1;
  return max(query(2 * node, left, mid, a, b), query(2 * node + 1, mid + 1, right, a, b));
}

int query_a(int x, int y) {
  int result = 0;

  while(seq[x] != seq[y]) {
    if(level[seq[x]] < level[seq[y]]) {
      swap(x, y);
    }

    result = max(result, query(1, 1, n, position[seq[x]], position[x]));
    x = parent[seq[x]];
  }

  if(level[x] < level[y]) {
    swap(x, y);
  }

  return max(result, query(1, 1, n, position[x], position[y]));
}

void solve() {
  dfs(1, 0);
  decompose(1, 1);
  
  for(int i = 1;i <= n;++i) {
    update(1, 1, n, position[i], vals[i]);
  }

  int x, y, z;
  for(int i = 1;i <= m;++i) {
    f>>x>>y>>z;
    if(!x) {
      update(1, 1, n, position[y], z);
    } else {
      g<<query_a(y, z)<<'\n';
    }
  }
}

int main() {
  read();
  solve();
  return 0;
}