Cod sursa(job #3240744)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 20 august 2024 18:37:11
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <bits/stdc++.h>
using namespace std;

const int kN = 1e5;

int v[kN], up[kN], sz[kN], hc[kN], dep[kN], lbl[kN], tin[kN];
vector<int> adj[kN], head, ord;

void dfs(int u) {
	sz[u] = 1;
	for(const auto &it : adj[u]) if(it != up[u]) {
		up[it] = u;
		dep[it] = dep[u] + 1;
		dfs(it);
		sz[u] += sz[it];
		if(!hc[u] || sz[hc[u]] < sz[it]) {
			hc[u] = it;
		}
	}
}

void dfs2(int u) {
	ord.emplace_back(u);
	tin[u] = ord.size() - 1;
	lbl[u] = head.size() - 1;
	if(hc[u]) {
		dfs2(hc[u]);
	}
	for(const auto &it : adj[u]) if(it != up[u] && it != hc[u]) {
		head.emplace_back(it);
		dfs2(it);
	}
}

void maxSelf(int &x, int y) {
	if(y > x) {
		x = y;
	}
}

struct segtree {
	int n;
	vector<int> tree;
	segtree() {}
	segtree(int n) : n(n), tree(n << 2 | 1) {}
	void build() {
		for(int i = 0; i < n; i++) {
			tree[i + n] = v[ord[i]];
		}
		for(int i = n - 1; i >= 1; i--) {
			tree[i] = max(tree[i << 1], tree[i << 1 | 1]);
		}
	}
	void update(int pos, int val) {
		pos += n;
		tree[pos] = val;
		for(pos >>= 1; pos >= 1; pos >>= 1) {
			tree[pos] = max(tree[pos << 1], tree[pos << 1 | 1]);
		}
	}
	int query(int a, int b) {
		if(a > b) {
			swap(a, b);
		}
		int res = 0;
		for(a += n, b += n; a <= b; a >>= 1, b >>= 1) {
			if(a & 1) {
				maxSelf(res, tree[a++]);
			}
			if(!(b & 1)) {
				maxSelf(res, tree[b--]);
			}
		}
		return res;
	}
} ds;

void update(int u, int val) {
	ds.update(tin[u], val);
}

int query(int u, int v) {
	int res = 0;
	while(lbl[u] != lbl[v]) {
		if(dep[head[lbl[u]]] > dep[head[lbl[v]]]) {
			maxSelf(res, ds.query(tin[u], tin[head[lbl[u]]]));
			u = up[head[lbl[u]]];
		} else {
			maxSelf(res, ds.query(tin[v], tin[head[lbl[v]]]));
			v = up[head[lbl[v]]];
		}
	}
	maxSelf(res, ds.query(tin[u], tin[v]));
	return res;
}

int main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	freopen("heavypath.in", "r", stdin);
	freopen("heavypath.out", "w", stdout);
	int n, q;
	cin >> n >> q;
	for(int i = 0; i < n; i++) {
		cin >> v[i];
	}
	for(int i = 1; i < n; i++) {
		int u, v;
		cin >> u >> v;
		u--; v--;
		adj[u].emplace_back(v);
		adj[v].emplace_back(u);
	}
	dfs(0);
	head.emplace_back(0);
	dfs2(0);
	ds = segtree(ord.size());
	ds.build();
	while(q--) {
		int op, u, v;
		cin >> op >> u >> v;
		u--;
		if(op == 0) {
			update(u, v);
		} else {
			v--;
			cout << query(u, v) << "\n";
		}
	}
	return 0;
}