fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. const int N = 2e5 + 5;
  12.  
  13. // Euler Tour cho Truy vấn Đường đi: Ta thêm đỉnh u vào Euler Tour khi dfs đi vào u và khi dfs đi ra khỏi u
  14. // Khi đó ta chia đường đi trên cây làm 2 loại:
  15. // Loại 1: u, v có quan hệ tổ tiên, giả sử u là tổ tiên của v:
  16. // - Khi đó đường đi từ u đến v sẽ tương ứng với đoạn [tin(u), tin(v)]
  17. // - Đặc biệt những đỉnh thuộc đường đi này sẽ xuất hiện đúng 1 lần trong đoạn,
  18. // còn những đỉnh không thuộc đường đi sẽ xuất hiện đúng 2 lần trong đoạn.
  19. // Loại 2: u, v không có quan hệ tổ tiên (nằm khác nhánh), giả sử tin(u) < tin(v):
  20. // - Khi đó đường đi từ u đến v sẽ tương ứng với đoạn [tout(u), tin(v)]
  21. // - Đặc biệt những đỉnh thuộc đường đi này sẽ xuất hiện đúng 1 lần trong đoạn,
  22. // còn những đỉnh không thuộc đường đi sẽ xuất hiện đúng 2 lần trong đoạn.
  23. // - Lưu ý ở trường hợp này cần xét riêng thêm lca(u, v) vì lca(u, v) sẽ không có trong đoạn này,
  24. // hoặc trong một số bài ta có thể tách thành 2 đường đi là lca(u, v) -> u và lca(u, v) -> v, đưa về lại loại 1.
  25.  
  26. // - Áp dụng vào bài này, với mỗi đỉnh u ta sẽ +a[u] vào vị trí tin[u] và -a[u] vào vị trí tout[u]
  27. // - Còn để tính tổng của đường đi từ 1 (gốc) đến u thì đơn giản là ta tính tổng đoạn [tin(1), tin(u)] = [1, tin(u)]
  28. // - Khi đó những đỉnh không thuộc đường đi (xuất hiện 2 lần trong đoạn) đều sẽ bị triệt tiêu,
  29. // còn những đỉnh thuộc đường đi (xuất hiện 1 lần trong đoạn) thì sẽ được tính vào tổng.
  30. // => Fenwick Tree / Segment Tree
  31.  
  32. int n, q;
  33. int a[N];
  34. vector<int> adj[N];
  35.  
  36. int tin[N], tout[N], timer;
  37.  
  38. void dfs(int u, int p) {
  39. tin[u] = ++timer;
  40. for (int v : adj[u]) {
  41. if (v == p) continue;
  42. dfs(v, u);
  43. }
  44. tout[u] = ++timer;
  45. }
  46.  
  47. struct Fenwick {
  48. int n;
  49. vector<ll> ft;
  50.  
  51. Fenwick(int n) : n(n) {
  52. ft.resize(n, 0);
  53. }
  54.  
  55. void update(int pos, int val) {
  56. for (; pos < n; pos += pos & (-pos)) {
  57. ft[pos] += val;
  58. }
  59. }
  60.  
  61. ll get(int pos) {
  62. ll ans = 0;
  63. for (; pos > 0; pos -= pos & (-pos)) {
  64. ans += ft[pos];
  65. }
  66. return ans;
  67. }
  68. };
  69.  
  70. int main() {
  71. ios::sync_with_stdio(false);
  72. cin.tie(nullptr);
  73. cin >> n >> q;
  74. for (int u = 1; u <= n; u++) cin >> a[u];
  75.  
  76. for (int i = 0; i < n - 1; i++) {
  77. int u, v;
  78. cin >> u >> v;
  79. adj[u].push_back(v);
  80. adj[v].push_back(u);
  81. }
  82.  
  83. timer = 0;
  84. dfs(1, -1);
  85.  
  86. Fenwick fenw(2 * n + 1);
  87. for (int u = 1; u <= n; u++) {
  88. fenw.update(tin[u], a[u]);
  89. fenw.update(tout[u], -a[u]);
  90. }
  91.  
  92. while (q--) {
  93. int type, u;
  94. cin >> type >> u;
  95.  
  96. if (type == 1) {
  97. int val; cin >> val;
  98. fenw.update(tin[u], -a[u] + val);
  99. fenw.update(tout[u], a[u] - val);
  100. a[u] = val;
  101. }
  102. else {
  103. ll ans = fenw.get(tin[u]);
  104. cout << ans << '\n';
  105. }
  106. }
  107. }
Success #stdin #stdout 0.01s 9668KB
stdin
5 3
4 2 5 2 1
1 2
1 3
3 4
3 5
2 4
1 3 2
2 4
stdout
11
8