Pagini recente » Cod sursa (job #1976888) | Cod sursa (job #2319423) | Cod sursa (job #2347586) | Cod sursa (job #1106902) | Cod sursa (job #3235356)
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#warning That's the baby, that's not my baby
typedef long long ll;
const int NMAX = 100'000;
std::vector<int> g[NMAX + 1];
int sz[NMAX + 1];
int depth[NMAX + 1];
int heavySon[NMAX + 1];
int a[NMAX + 1];
int parent[NMAX + 1];
void dfs(int u) {
depth[u] = depth[parent[u]] + 1;
sz[u] = 1;
heavySon[u] = 0;
for (const auto &v : g[u]) {
if (v != parent[u]) {
parent[v] = u;
dfs(v);
sz[u] += sz[v];
if (sz[v] > sz[heavySon[u]]) {
heavySon[u] = v;
}
}
}
}
int head[NMAX + 1];
int paths;
int timer;
int label[NMAX + 1];
int tin[NMAX + 1];
void decomp(int u) {
tin[u] = ++timer;
if (heavySon[u] != 0) {
decomp(heavySon[u]);
label[u] = label[heavySon[u]];
} else {
label[u] = ++paths;
}
head[label[u]] = u;
for (const auto &v : g[u]) {
if (v != parent[u] && v != heavySon[u]) {
decomp(v);
}
}
}
struct segtree {
std::vector<int> aint;
int n;
segtree() {}
segtree(int _n) {
n = _n;
aint.resize(2 * n + 1, 0);
}
void update(int pos, const int &val) {
for (aint[pos += n - 1] = val; pos > 1; pos >>= 1) {
aint[pos >> 1] = std::max(aint[pos], aint[pos ^ 1]);
}
}
int query(int l, int r) {
int ret = 0;
for (l += n - 1, r += n; l < r; l >>= 1, r >>= 1) {
if (l & 1) {
ret = std::max(ret, aint[l++]);
}
if (r & 1) {
ret = std::max(ret, aint[--r]);
}
}
return ret;
}
};
segtree aint;
int maxPath(int u, int v) {
int ret = 0;
while (label[u] != label[v]) {
if (depth[head[label[u]]] > depth[head[label[v]]]) {
ret = std::max(ret, aint.query(tin[u], tin[head[label[u]]]));
u = parent[head[label[u]]];
} else {
ret = std::max(ret, aint.query(tin[v], tin[head[label[v]]]));
v = parent[head[label[v]]];
}
}
if (tin[u] > tin[v]) {
std::swap(u, v);
}
ret = std::max(ret, aint.query(tin[u], tin[v]));
return ret;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
#ifndef LOCAL
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
#endif
int n, q;
std::cin >> n >> q;
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
for (int i = 1; i < n; i++) {
int u, v;
std::cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1);
decomp(1);
aint = n;
for (int i = 1; i <= n; i++) {
tin[i] = n - tin[i] + 1;
aint.update(tin[i], a[i]);
}
while (q--) {
int type, x, y;
std::cin >> type >> x >> y;
if (type == 0) {
aint.update(tin[x], y);
} else {
std::cout << maxPath(x, y) << '\n';
}
}
return 0;
}