Pagini recente » Cod sursa (job #1609904) | Cod sursa (job #3284564) | Cod sursa (job #811292) | Cod sursa (job #1661853) | Cod sursa (job #3240744)
#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;
}