Pagini recente » Cod sursa (job #1222955) | Borderou de evaluare (job #1569356) | Cod sursa (job #472480) | Cod sursa (job #1285888) | Cod sursa (job #2710548)
#include <bits/stdc++.h>
using namespace std;
struct SplayTree {
struct Node {
int ch[2] = {0, 0}, p = 0;
int self = 0, path = 0;
};
vector<Node> T;
SplayTree(int n) : T(n + 1) {}
void push(int x) {}
void pull(int x) {
int l = T[x].ch[0], r = T[x].ch[1]; push(l); push(r);
T[x].path = max({T[l].path, T[x].self, T[r].path});
}
void set(int x, int d, int y) {
T[x].ch[d] = y; T[y].p = x; pull(x);
}
void splay(int x) {
auto dir = [&](int x) {
int p = T[x].p; if (!p) return -1;
return T[p].ch[0] == x ? 0 : T[p].ch[1] == x ? 1 : -1;
};
auto rotate = [&](int x) {
int y = T[x].p, z = T[y].p, dx = dir(x), dy = dir(y);
set(y, dx, T[x].ch[!dx]); set(x, !dx, y);
if (~dy) set(z, dy, x);
T[x].p = z;
};
for (push(x); ~dir(x); ) {
int y = T[x].p, z = T[y].p;
push(z); push(y); push(x);
int dx = dir(x), dy = dir(y);
if (~dy) rotate(dx != dy ? x : y);
rotate(x);
}
}
};
struct LinkCut : SplayTree {
LinkCut(int n) : SplayTree(n) {}
int access(int x) {
int u = x, v = 0;
for (; u; v = u, u = T[u].p) {
splay(u);
int& ov = T[u].ch[1];
ov = v; pull(u);
}
return splay(x), v;
}
// Rooted tree LCA. Returns 0 if u and v arent connected.
int LCA(int u, int v) {
if (u == v) return u;
access(u); int ret = access(v);
return T[u].p ? ret : 0;
}
// Query path [u..v].
int Path(int u, int v) {
int lca = LCA(u, v);
int ret = T[lca].self;
access(u); splay(lca);
ret = max(ret, T[T[lca].ch[1]].path);
access(v); splay(lca);
ret = max(ret, T[T[lca].ch[1]].path);
return ret;
}
// Update vertex with value v.
void Update(int u, int v) {
access(u); T[u].self = v; pull(u);
}
};
int main() {
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
int n, q; cin >> n >> q;
LinkCut LC(n);
for (int i = 1; i <= n; ++i) {
int x; cin >> x;
LC.Update(i, x);
}
vector<vector<int>> graph(n + 1);
for (int i = 1; i < n; ++i) {
int a, b; cin >> a >> b;
graph[a].push_back(b); graph[b].push_back(a);
}
{
vector<int> q = {1};
for (int i = 0; i < n; ++i) {
int node = q[i];
for (auto vec : graph[node]) {
if (vec != LC.T[node].p) {
LC.T[vec].p = node;
q.push_back(vec);
}
}
}
}
for (int i = 0; i < q; ++i) {
int t, u, v; cin >> t >> u >> v;
if (t == 0)
LC.Update(u, v);
else
cout << LC.Path(u, v) << '\n';
}
return 0;
}