Pagini recente » Cod sursa (job #2699167) | Cod sursa (job #1717352) | Cod sursa (job #2660020) | Cod sursa (job #1958810) | Cod sursa (job #2689463)
#include <bits/stdc++.h>
using namespace std;
struct Splay {
struct Node {
int ch[2] = {-1, -1}, p = -1;
int path, val = 0; // Path aggregates
int sub, vir = 0; // Subtree aggregates
bool flip; // Lazy tags
};
vector<Node> T;
Splay(int n) : T(n) {}
void push(int x) {
if (x == -1) return;
if (T[x].flip) {
for (int y : {T[x].ch[0], T[x].ch[1]}) if (~y)
T[y].flip ^= 1;
swap(T[x].ch[0], T[x].ch[1]);
T[x].flip = false;
}
}
void pull(int x) {
T[x].path = T[x].val;
T[x].sub = T[x].vir + T[x].val;
for (int y : {T[x].ch[0], T[x].ch[1]}) if (~y) {
T[x].path = max(T[x].path, T[y].path);
T[x].sub += T[y].sub;
}
}
void set(int x, int d, int y) {
T[x].ch[d] = y, pull(x);
if (~y) T[y].p = x;
}
void splay(int x) {
auto dir = [&](int x) {
for (int p = T[x].p, z = 0; z < 2; ++z)
if ((~p) && T[p].ch[z] == x)
return z;
return -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); else T[x].p = z;
};
/// Push lazy tags
static vector<int> stk;
for (stk.push_back(x); ~dir(x); stk.push_back(x = T[x].p));
while (stk.size()) push(x = stk.back()), stk.pop_back();
/// Rotate up
while (~dir(x)) {
int y = T[x].p, z = T[y].p, dx = dir(x), dy = dir(y);
if (~dy) rotate(dx != dy ? x : y);
rotate(x);
}
}
};
struct LinkCut : Splay {
LinkCut(int n) : Splay(n) {}
void access(int x) {
for (int u = x, v = -1; (~u); v = u, u = T[u].p) {
splay(u);
int& r = T[u].ch[1];
if (~r) T[u].vir += T[r].sub;
r = v;
if (~r) T[u].vir -= T[r].sub;
pull(u);
}
splay(x);
assert(T[x].ch[1] == -1);
}
void reroot(int u) { access(u); T[u].flip ^= 1; push(u); }
void Link(int u, int v) {
reroot(u); access(v);
T[u].p = v; T[v].vir += T[u].sub;
}
void Cut(int u, int v) {
reroot(u); access(v);
set(v, 0, T[u].p = -1);
}
};
int main() {
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
int n, m; cin >> n >> m;
LinkCut lc(n);
for (int i = 0; i < n; ++i) {
cin >> lc.T[i].val;
lc.pull(i);
}
for (int i = 1; i < n; ++i) {
int a, b; cin >> a >> b; --a; --b;
lc.Link(a, b);
}
for (int i = 0; i < m; ++i) {
int t, x, y; cin >> t >> x >> y; --x;
if (t == 0) {
lc.reroot(x); lc.T[x].val = y; lc.pull(x);
} else {
--y; lc.reroot(x); lc.access(y);
cout << lc.T[y].path << '\n';
}
}
return 0;
}