Cod sursa(job #3032882)

Utilizator dorufDoru Floare doruf Data 22 martie 2023 22:00:11
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>
using namespace std;
#define eb emplace_back

const string TASK("heavypath");

ifstream fin(TASK + ".in");
ofstream fout(TASK + ".out");

struct SegmentTree {
  vector<int> tree; int n = 0;
  void init(int sz) {n = sz; tree = vector<int> (4 * n + 5);}
  int query(int l, int r) {return Query(1, 1, n, l, r);}
  void update(int p, int v) {Update(1, 1, n, p, v);}
  void Update(int x, int l, int r, int p, int v) {
    if (l == r) {tree[x] = v; return;}
    int mid = (l + r) / 2;
    if (p <= mid) Update(2*x, l, mid, p, v);
    else Update(2*x+1, mid+1, r, p, v);
    tree[x] = max(tree[2*x], tree[2*x+1]);
  }
  int Query(int x, int l, int r, int ql, int qr) {
    if (r < ql || qr < l) return 0;
    if (ql <= l && r <= qr) return tree[x];
    int mid = (l + r) / 2;
    return max(Query(2*x,l,mid,ql,qr),Query(2*x+1,mid+1,r,ql,qr));
  }
};
const int N = 1e5 + 5;
int what[N], where[N];
SegmentTree chain[N];
int n, q, val[N], sz[N], heavy_son[N], paths = 1;
int chain_size[N], depth[N], start[N], up[N];
vector<int> adj[N];

void dfssz(int u, int parent) {
  sz[u] = 1;
  depth[u] = depth[parent] + 1;
  up[u] = parent;
  int mx = 0;
  for (auto v : adj[u])
    if (v != parent) {
      dfssz(v, u);
      sz[u] += sz[v];
      if (!mx || sz[mx] < sz[v])
        mx = v;
    }
  heavy_son[u] = mx;
}

void dfspath(int u, int parent, int path, int pos) {
  what[u] = path;
  where[u] = pos;
  if (pos == 1)
    start[path] = u;
  ++chain_size[path];
  for (auto v : adj[u]) {
    if (v == parent) continue;
    if (v == heavy_son[u])
      dfspath(v, u, path, pos + 1);
    else dfspath(v, u, ++paths, 1);
  }
}

int hp_query(int u, int v) {
  //cout << u << ' ' << v << '\n';
  if (what[u] == what[v])
    return chain[what[u]].query(min(where[u],where[v]),max(where[u],where[v]));
  if (depth[start[what[u]]] < depth[start[what[v]]])
    swap(u, v);
  int wu = what[u];
  return max(chain[wu].query(where[start[wu]], where[u]), hp_query(up[start[wu]], v));
}

int main() {
  fin >> n >> q;
  for (int i = 1; i <= n; ++i)
    fin >> val[i];
  for (int u, v, i = 1; i < n; ++i) {
    fin >> u >> v;
    adj[u].eb(v); adj[v].eb(u);
  }
  dfssz(1, 0);
  dfspath(1, 0, 1, 1);
  //for (int i = 1; i <= n; ++i)
  //  fout << i << ' ' << what[i] << ' ' << where[i] << '\n';
  for (int i = 1; i <= n; ++i) {
    if (!chain[what[i]].n)
      chain[what[i]].init(chain_size[what[i]]);
    chain[what[i]].update(where[i], val[i]);
  }
  while (q--) {
    int x, y, type;
    fin >> type >> x >> y;
    if (type == 0)
      chain[what[x]].update(where[x], y);
    else fout << hp_query(x, y) << '\n';
  }
}