Pagini recente » Cod sursa (job #1918392) | Cod sursa (job #1794066) | Cod sursa (job #1834503) | Cod sursa (job #1894038) | Cod sursa (job #2596430)
#include <bits/stdc++.h>
using namespace std;
struct Node { // Splay tree. Root's pp contains tree's parent.
Node *p = 0, *pp = 0, *c[2];
bool flip = 0;
int dp = 0, val = 0;
Node() { c[0] = c[1] = 0; fix(); }
void fix() {
dp = val;
if (c[0]) {
c[0]->p = this;
dp = max(dp, c[0]->dp);
}
if (c[1]) {
c[1]->p = this;
dp = max(dp, c[1]->dp);
}
}
void push_flip() {
if (!flip) return;
flip = 0; swap(c[0], c[1]);
if (c[0]) c[0]->flip ^= 1;
if (c[1]) c[1]->flip ^= 1;
}
int up() { return p ? p->c[1] == this : -1; }
void rot(int i, int b) {
int h = i ^ b;
Node *x = c[i], *y = b == 2 ? x : x->c[h], *z = b ? y : x;
if ((y->p = p)) p->c[up()] = y;
c[i] = z->c[i ^ 1];
if (b < 2) {
x->c[h] = y->c[h ^ 1];
z->c[h ^ 1] = b ? x : this;
}
y->c[i ^ 1] = b ? this : x;
fix(); x->fix(); y->fix();
if (p) p->fix();
swap(pp, y->pp);
}
void splay() { /// Splay this up to the root. Always finishes without flip set.
for (push_flip(); p; ) {
if (p->p) p->p->push_flip();
p->push_flip(); push_flip();
int c1 = up(), c2 = p->up();
if (c2 == -1) p->rot(c1, 2);
else p->p->rot(c2, c1 != c2);
}
}
Node* first() { /// Return the min element of the subtree rooted at this, splayed to the top.
push_flip();
return c[0] ? c[0]->first() : (splay(), this);
}
};
struct LinkCut {
vector<Node> node;
LinkCut(int N) : node(N) {}
void Link(int u, int v) { // add an edge (u, v)
make_root(&node[u]);
node[u].pp = &node[v];
}
/// Move u to root of represented tree.
void make_root(Node* u) {
access(u);
u->splay();
if(u->c[0]) {
u->c[0]->p = 0;
u->c[0]->flip ^= 1;
u->c[0]->pp = u;
u->c[0] = 0;
u->fix();
}
}
/// Move u to root aux tree. Return the root of the root aux tree.
Node* access(Node* u) {
u->splay();
while (Node* pp = u->pp) {
pp->splay(); u->pp = 0;
if (pp->c[1]) {
pp->c[1]->p = 0; pp->c[1]->pp = pp; }
pp->c[1] = u; pp->fix(); u = pp;
}
return u;
}
void Update(int u, int val) {
node[u].splay();
node[u].val = val;
}
int Query(int u, int v) {
make_root(&node[u]);
access(&node[v]);
node[v].splay();
int ans = node[v].val;
if (node[v].c[0])
ans = max(ans, node[v].c[0]->dp);
return ans;
}
};
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.node[i].val;
}
for (int i = 1; i < n; ++i) {
int a, b; cin >> a >> b;
lc.Link(a - 1, b - 1);
}
for (int i = 0; i < m; ++i) {
int t, a, b; cin >> t >> a >> b;
if (t == 0) lc.Update(a - 1, b);
else cout << lc.Query(a - 1, b - 1) << '\n';
}
return 0;
}