Advertisement
MathQ_

Untitled

Aug 4th, 2022
820
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.13 KB | None | 0 0
  1. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
  2. #pragma GCC optimize("Ofast")
  3. #pragma GCC optimize("unroll-loops")
  4.  
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <iterator>
  8. #include <iomanip>
  9. #include <cmath>
  10. #include <ctime>
  11. #include <vector>
  12. #include <deque>
  13. #include <queue>
  14. #include <set>
  15. #include <map>
  16. #include <stack>
  17. #include <string>
  18. #include <random>
  19. #include <numeric>
  20. #include <unordered_set>
  21. #include <bitset>
  22. #include <random>
  23.  
  24. typedef unsigned long long ull;
  25. typedef long long ll;
  26. typedef long double lb;
  27.  
  28. #define fast ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  29. #define file_in freopen("input.txt", "r", stdin);
  30. #define file_in_out freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
  31. #define mp make_pair
  32. #define pii pair<int, int>
  33. #define all(x) (x).begin(), (x).end()
  34. #define fi first
  35. #define se second
  36.  
  37. using namespace std;
  38.  
  39. template<typename T>
  40. istream& operator>>(istream &in, vector<T> &v) {
  41.     for (auto &it : v) {
  42.         in >> it;
  43.     }
  44.     return in;
  45. }
  46.  
  47. template<typename T>
  48. ostream& operator<<(ostream &out, vector<T> &v) {
  49.     if (!v.empty()) {
  50.         out << v.front();
  51.         for (int i = 1; i < v.size(); ++i) {
  52.             out << " " << v[i];
  53.         }
  54.     }
  55.     return out;
  56. }
  57.  
  58. template<typename T>
  59. istream& operator>>(istream &in, pair<T, T> &v) {
  60.     in >> v.fi >> v.se;
  61.     return in;
  62. }
  63.  
  64. template<typename T1, typename T2>
  65. ostream& operator<<(ostream &out, pair<T1, T2> &v) {
  66.     out << v.fi << " " << v.se;
  67.     return out;
  68. }
  69.  
  70. struct node {
  71.     ll sum = 0, add = 0;
  72. };
  73.  
  74. struct seg_tree {
  75.     vector<ll> a;
  76.     vector<node> t;
  77.  
  78.     seg_tree(vector<ll> b) {
  79.         int n = b.size();
  80.         a = b;
  81.         t.resize(4 * n);
  82.         build(0, 0, n);
  83.     }
  84.  
  85.     void push(int id) {
  86.         t[id].sum += t[id].add;
  87.         if (id * 2 + 1 < t.size()) t[id * 2 + 1].add += t[id].add;
  88.         if (id * 2 + 2 < t.size()) t[id * 2 + 2].add += t[id].add;
  89.         t[id].add = 0;
  90.     }
  91.  
  92.     void build(int id, int l, int r) {
  93.         if (l + 1 == r) {
  94.             t[id].sum = a[l];
  95.             return;
  96.         }
  97.         int m = (l + r) / 2;
  98.         build(id * 2 + 1, l, m);
  99.         build(id * 2 + 2, m, r);
  100.         t[id].sum = t[id * 2 + 1].sum + t[id * 2 + 2].sum;
  101.     }
  102.  
  103.     ll get(int id, int l, int r, int i) {
  104.         if (l + 1 == r) {
  105.             push(id);
  106.             return t[id].sum;
  107.         }
  108.         push(id);
  109.         int m = (l + r) / 2;
  110.         if (i < m) {
  111.             return get(id * 2 + 1, l, m, i);
  112.         } else {
  113.             return get(id * 2 + 2, m, r, i);
  114.         }
  115.     }
  116.  
  117.     void update(int id, int l, int r, int lq, int rq, int x) {
  118.         if (lq >= r || l >= rq) {
  119.             return;
  120.         }
  121.         if (lq <= l && r <= rq) {
  122.             t[id].add += x;
  123.             push(id);
  124.             return;
  125.         }
  126.         push(id);
  127.         int m = (l + r) / 2;
  128.         update(id * 2 + 1, l, m, lq, rq, x);
  129.         update(id * 2 + 2, m, r, lq, rq, x);
  130.         t[id].sum = t[id * 2 + 1].sum + t[id * 2 + 2].sum;
  131.     }
  132. };
  133.  
  134. const int LOG = 20;
  135. int timer = 0;
  136. vector<vector<int>> g;
  137. vector<vector<int>> up;
  138. vector<int> val;
  139. vector<ll> euler;
  140. vector<ll> dist;
  141. vector<int> tin, tout;
  142.  
  143. void resize_all(int n) {
  144.     val.resize(n);
  145.     g.resize(n);
  146.     dist.resize(n);
  147.     tin.resize(n);
  148.     tout.resize(n);
  149.     up.resize(n, vector<int>(LOG));
  150. }
  151.  
  152. void dfs(int v, int p = 0) {
  153.     tin[v] = timer++;
  154.     euler.push_back(v);
  155.     up[v][0] = p;
  156.     for (int i = 1; i < LOG; ++i) {
  157.         up[v][i] = up[up[v][i - 1]][i - 1];
  158.     }
  159.     for (auto u : g[v]) {
  160.         if (u != p) {
  161.             dist[u] = dist[v] + val[u];
  162.             dfs(u, v);
  163.         }
  164.     }
  165.     euler.push_back(v);
  166.     tout[v] = timer++;
  167. }
  168.  
  169. bool isAnc(int u, int v) {
  170.     return tin[u] <= tin[v] && tout[v] <= tout[u];
  171. }
  172.  
  173. int lca(int v, int u) {
  174.     if (isAnc(v, u)) return v;
  175.     if (isAnc(u, v)) return u;
  176.     for (int i = LOG - 1; i >= 0; --i) {
  177.         if (!isAnc(up[v][i], u)) {
  178.             v = up[v][i];
  179.         }
  180.     }
  181.     return up[v][0];
  182. }
  183.  
  184. int main() {
  185.     fast
  186.     // file_in
  187.     // file_in_out
  188.  
  189.     int n;
  190.     cin >> n;
  191.     resize_all(n);
  192.     cin >> val;
  193.     dist[0] = val[0];
  194.     int v, u, x;
  195.     for (int i = 0; i < n - 1; ++i) {
  196.         cin >> v >> u;
  197.         --v; --u;
  198.         g[v].push_back(u);
  199.         g[u].push_back(v);
  200.     }
  201.     dfs(0);
  202.     for (auto &it : euler) {
  203.         it = dist[it];
  204.     }
  205.     seg_tree s(euler);
  206.     int m = euler.size();
  207.    
  208.     int q;
  209.     cin >> q;
  210.     char type;
  211.     while (q--) {
  212.         cin >> type;
  213.         if (type == '?') {
  214.             cin >> v >> u;
  215.             --v; --u;
  216.             int lca_v_u = lca(v, u);
  217.             ll sum_v = s.get(0, 0, m, tin[v]);
  218.             ll sum_u = s.get(0, 0, m, tin[u]);
  219.             ll sum_lca_v_u = s.get(0, 0, m, tin[lca_v_u]);
  220.             cout << sum_v + sum_u - 2 * sum_lca_v_u + val[lca_v_u] << '\n';
  221.         } else {
  222.             cin >> v >> x;
  223.             --v;
  224.             s.update(0, 0, m, tin[v], tout[v] + 1, x - val[v]);
  225.             val[v] = x;
  226.         }
  227.     }
  228.     return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement