Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <unordered_map>
- #include <string>
- #include <map>
- #include <cmath>
- #include <algorithm>
- #include <set>
- #include <chrono>
- #include <random>
- #include <iomanip>
- #include <fstream>
- #define ll long long
- #define len(v) (int)v.size()
- #define all(v) v.begin(), v.end()
- #define rall(v) v.rbegin(), v.rend()
- #define pii pair<int, int>
- #define vi vector<int>
- #define vii vector<vector<int>>
- #define ull unsigned long long
- //#define int long long
- const int maxn = 1e5 + 10;
- const int C = 20;
- const int logn = 20;
- const int inf = 1e9;
- const int mod = 1e9 + 7;
- const int M = 1e9;
- const ull M2 = 998244353;
- using namespace std;
- int n, m, l = 1, rootval;
- vector<vector<int>> g, up;
- int timer = 0;
- vector<ll> a, tin, tout;
- vector<ll> pref;
- bool ancestor(int a, int b) {
- return (tin[a] <= tin[b]) && (tout[a] >= tout[b]);
- }
- int lca(int a, int b) {
- if (ancestor(a, b)) return a;
- if (ancestor(b, a)) return b;
- for (int i = l; i >= 0; --i) {
- if (!ancestor(up[a][i], b))
- a = up[a][i];
- }
- return up[a][0];
- }
- void dfs(int v, int p = 1) {
- tin[v] = timer++;
- up[v][0] = p;
- for (int i = 1; i <= l; ++i)
- up[v][i] = up[up[v][i - 1]][i - 1];
- for (auto u : g[v]) {
- if (u != p)
- dfs(u, v);
- }
- tout[v] = timer;
- }
- struct segtree {
- vector<ll> t;
- vector<ll> a;
- void init(vector<ll>& _a) {
- a = _a;
- t.resize(len(a) * 4 + 10);
- }
- void build(int v, int l, int r) {
- if (l + 1 == r) {
- t[v] = a[l];
- return;
- }
- int m = (l + r) / 2;
- build(2 * v + 1, l, m);
- build(2 * v + 2, m, r);
- }
- void upd(int v, int l, int r, int ql, int qr, int x) {
- if (ql >= qr) return;
- if (l >= r) return;
- if (l == ql && r == qr) {
- t[v] += x;
- return;
- }
- int m = (l + r) / 2;
- upd(2 * v + 1, l, m, ql, min(qr, m), x);
- upd(2 * v + 2, m, r, max(ql, m), qr, x);
- }
- ll get(int v, int l, int r, int pos) {
- if (l + 1 == r)
- return t[v];
- int m = (l + r) / 2;
- if (pos < m)
- return t[v] + get(2 * v + 1, l, m, pos);
- else
- return t[v] + get(2 * v + 2, m, r, pos);
- }
- };
- void dfspref(int v, ll curs) {
- pref[tin[v]] = curs + a[v];
- curs += a[v];
- for (auto u : g[v]) {
- if (u != up[v][0])
- dfspref(u, curs);
- }
- }
- ll getval(int v, segtree& t) {
- if (v == 1)
- return rootval;
- return (t.get(0, 0, n, tin[v]) - t.get(0, 0, n, tin[up[v][0]]));
- }
- void solve() {
- cin >> n;
- g.resize(n + 1);
- up.resize(n + 1);
- for (auto& e : up)
- e.resize(logn);
- tin.resize(n + 1);
- tout.resize(n + 1);
- a.resize(n + 1);
- pref.resize(n);
- for (int i = 1; i <= n; ++i)
- cin >> a[i];
- for (int i = 1; i < n; ++i) {
- int u, v; cin >> u >> v;
- g[u].push_back(v);
- g[v].push_back(u);
- }
- dfs(1);
- dfspref(1, 0ll);
- rootval = a[1];
- segtree t;
- t.init(pref);
- t.build(0, 0, n);
- cin >> m;
- while (m--) {
- char tp; cin >> tp;
- if (tp == '?') {
- int u, v; cin >> u >> v;
- int lcauv = lca(u, v);
- ll lcas = t.get(0, 0, n, tin[lcauv]);
- ll lcaval = getval(lcauv, t);
- cout << (t.get(0, 0, n, tin[u]) + t.get(0, 0, n, tin[v]) - lcas - lcas + lcaval) << "\n";
- }
- else {
- int v, x; cin >> v >> x;
- t.upd(0, 0, n, tin[v], tout[v], (x - getval(v, t)));
- if (v == 1)
- rootval = x;
- }
- }
- }
- signed main() {
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement