Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * author: 2lasy2code
- * created: 16.03.2021 15:42:12
- * task: Link
- **/
- #include <bits/stdc++.h>
- #define ioBoost ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr)
- using namespace std;
- #define int long long
- #define all(x) (x).begin(), (x).end()
- #define rep(i, l, r) for(int i = l; i < r; ++i)
- class node {
- public:
- int val, res, id, d;
- node *l = nullptr, *r = nullptr, *p = nullptr;
- bool rev = false;
- int sz = 1;
- explicit node(int _id, int _val) : id(_id), val(_val), res(_val), d(0) {}
- void pull() {
- sz = 1;
- res = val + d;
- if (l != nullptr) {
- l->p = this;
- sz += l->sz;
- res = max(res, (l->res + l->d));
- }
- if (r != nullptr) {
- r->p = this;
- sz += r->sz;
- res = max(res, (r->res + r->d));
- }
- }
- void push() {
- if (rev) {
- if (l != nullptr)
- l->rev ^= 1;
- if (r != nullptr)
- r->rev ^= 1;
- swap(l, r);
- rev = false;
- }
- val += d;
- res += d;
- if (l != nullptr)
- l->d += d;
- if (r != nullptr)
- r->d += d;
- d = 0;
- }
- };
- bool is_bst_root(node *v) {
- if (v == nullptr)
- return false;
- v->push();
- return (v->p == nullptr || (v->p->l != v && v->p->r != v));
- }
- void rotate(node *v) {
- node *u = v->p;
- u->push(), v->push();
- v->p = u->p;
- if (v->p != nullptr) {
- if (v->p->l == u)
- v->p->l = v;
- if (v->p->r == u)
- v->p->r = v;
- }
- if (v == u->l)
- u->l = v->r, v->r = u;
- else
- u->r = v->l, v->l = u;
- u->pull(), v->pull();
- }
- void splay(node *v) {
- if (v == nullptr)
- return;
- while (!is_bst_root(v)) {
- node *u = v->p;
- if (!is_bst_root(u)) {
- if ((u->l == v) ^ (u->p->l == u)) {
- rotate(v);
- } else {
- rotate(u);
- }
- }
- rotate(v);
- }
- v->push();
- }
- int get_size(node *v) {
- splay(v);
- return (v != nullptr ? v->sz : 0);
- }
- int get_res(node *v) {
- splay(v);
- return (v != nullptr ? v->res + v->d : 0);
- }
- node *expose(node *v) {
- if (v == nullptr) return nullptr;
- node *c = nullptr;
- for (auto u = v; u != nullptr; u = u->p) {
- splay(u);
- u->r = c;
- u->pull();
- c = u;
- }
- splay(v);
- return c;
- }
- void evert(node *&v) {
- expose(v);
- v->rev ^= 1;
- }
- node *root(node *v) {
- expose(v);
- while (v->l) {
- v = v->l;
- v->push();
- }
- expose(v);
- return v;
- }
- node *parent(node *v) {
- expose(v);
- if (v->l == nullptr)
- return nullptr;
- v = v->l;
- v->push();
- while (v->r) {
- v = v->r;
- v->push();
- }
- return v;
- }
- bool path(node *v, node *u) {
- if (v == u) return true;
- expose(u), expose(v);
- return u->p != nullptr;
- }
- void link(node *v, node *u) {
- if (path(v, u)) return;
- evert(v);
- v->p = u;
- }
- void cut(node *v) {
- expose(v);
- if (v->l == nullptr)
- return;
- v->l->p = nullptr;
- v->l = nullptr;
- }
- node *lca(node *v, node *u) {
- if (!path(v, u))
- return nullptr;
- expose(v);
- return expose(u);
- }
- int depth(node *v) {
- expose(v);
- return get_size(v->l);
- }
- void print(node *t) {
- if (t == nullptr) return;
- print(t->l);
- cerr << t->val << ' ';
- print(t->r);
- }
- void write(node *t) {
- cerr << "-----------------\n";
- print(t);
- cerr << "\n-----------------\n";
- }
- void debug_node(node *v, string pref = "") {
- if (v != nullptr) {
- v->push();
- debug_node(v->r, pref + " ");
- cerr << pref << "-" << " " << v->val << '\n';
- debug_node(v->l, pref + " ");
- } else {
- cerr << pref << "-" << " " << "nullptr " << '\n';
- }
- }
- int query(node* v, node* u) {
- if (!path(v, u)) return 0;
- evert(v);
- expose(u);
- return u->res;
- }
- void update(node* v, node* u, int value) {
- if (!path(v, u))
- return;
- evert(v);
- expose(u);
- u->d += value;
- }
- void solveTestCase() {
- int n;
- cin >> n;
- vector<node*> tree(n);
- rep(i, 0, n) {
- int w;
- cin >> w;
- tree[i] = new node(i, w);
- }
- rep(i, 0, n - 1) {
- int v, u;
- cin >> v >> u;
- --v, --u;
- link(tree[v], tree[u]);
- }
- int m;
- cin >> m;
- rep(i, 0, m) {
- char t = '?';
- cin >> t;
- if (t == '?') {
- int v, u;
- cin >> v >> u;
- --v, --u;
- cout << query(tree[v], tree[u]) << '\n';
- } else {
- int v, x;
- cin >> v >> x;
- --v;
- update(tree[v], tree[v], x - query(tree[v], tree[v]));
- }
- }
- }
- signed main() {
- ioBoost;
- int tt = 1;
- // cin >> tt;
- while (tt--)
- solveTestCase();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement