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. // - Ta đã biết dist(u, v) = dist(1, u) + dist(1, v) - 2 * dist(1, lca(u, v))
  12. // => Tức mọi truy vấn dist(u, v) đều có thể biến đổi thành các truy vấn có dạng dist(1, i) (1 <= i <= n)
  13. // => Áp dụng bài Path Queries đã được học ở Chương Euler Tour
  14. // - Nhưng lưu ý ở đây truy vấn update là update 1 cạnh chứ không phải update 1 đỉnh như bài Path Queries
  15. // - Nhận xét: với mỗi đỉnh u trong cây (trừ đỉnh 1), ta có p[u] = cha của u, là duy nhất với mỗi u
  16. // do đó với mỗi cạnh (u, p[u]) thì ta cho u làm đỉnh đại diện,
  17. // đưa trọng số w của cạnh (u, p[u]) sang làm trọng số của đỉnh u -> a[u]
  18. // - Làm như thế thì các truy vấn có dạng (anc, u) với anc là tổ tiên của u sẽ bị dư ra a[anc],
  19. // nhưng riêng với trường hợp anc = 1 thì không sao cả tại vì a[1] = 0
  20.  
  21. const int N = 2e5 + 5;
  22. const int LOG = 18;
  23.  
  24. struct AdjEdge {
  25. int to;
  26. int w;
  27. int idx;
  28. };
  29.  
  30. int n, q;
  31. int a[N]; // a[u] = Trọng số của cạnh (u, p[u]) = Trọng số của cạnh do u đại diện
  32. vector<AdjEdge> adj[N];
  33. int edge_to_node[N]; // edge_to_node[i] = Đỉnh đại diện cho cạnh thứ i
  34.  
  35. int up[LOG][N];
  36. int tin[N], tout[N], timer;
  37.  
  38. void dfs(int u, int p) {
  39. tin[u] = ++timer;
  40. up[0][u] = p;
  41. for (int i = 1; i < LOG; i++) {
  42. up[i][u] = up[i - 1][up[i - 1][u]];
  43. }
  44. for (auto e : adj[u]) {
  45. int v = e.to;
  46. if (v == p) continue;
  47. edge_to_node[e.idx] = v;
  48. a[v] = e.w;
  49. dfs(v, u);
  50. }
  51. tout[u] = ++timer;
  52. }
  53.  
  54. bool isAncestor(int u, int v) {
  55. return (tin[u] <= tin[v] && tout[v] <= tout[u]);
  56. }
  57.  
  58. int lca(int u, int v) {
  59. if (isAncestor(u, v)) return u;
  60. if (isAncestor(v, u)) return v;
  61. for (int i = LOG - 1; i >= 0; i--) {
  62. if (!isAncestor(up[i][u], v)) {
  63. u = up[i][u];
  64. }
  65. }
  66. return up[0][u];
  67. }
  68.  
  69. struct Fenwick {
  70. int n;
  71. vector<ll> ft;
  72.  
  73. Fenwick(int n) : n(n) {
  74. ft.resize(n, 0);
  75. }
  76.  
  77. void update(int pos, int val) {
  78. for (; pos < n; pos += pos & (-pos)) {
  79. ft[pos] += val;
  80. }
  81. }
  82.  
  83. ll get(int pos) {
  84. ll ans = 0;
  85. for (; pos > 0; pos -= pos & (-pos)) {
  86. ans += ft[pos];
  87. }
  88. return ans;
  89. }
  90. };
  91.  
  92. int main() {
  93. ios::sync_with_stdio(false);
  94. cin.tie(nullptr);
  95. cin >> n;
  96. for (int i = 1; i <= n - 1; i++) {
  97. int u, v, w;
  98. cin >> u >> v >> w;
  99. adj[u].push_back({v, w, i});
  100. adj[v].push_back({u, w, i});
  101. }
  102. cin >> q;
  103.  
  104. timer = 0;
  105. dfs(1, 1);
  106.  
  107. Fenwick fenw(2 * n + 1);
  108. for (int u = 1; u <= n; u++) {
  109. fenw.update(tin[u], a[u]);
  110. fenw.update(tout[u], -a[u]);
  111. }
  112.  
  113. while (q--) {
  114. int type; cin >> type;
  115.  
  116. if (type == 1) {
  117. int i, w;
  118. cin >> i >> w;
  119. int u = edge_to_node[i];
  120. fenw.update(tin[u], -a[u] + w);
  121. fenw.update(tout[u], a[u] - w);
  122. a[u] = w;
  123. }
  124. else {
  125. int u, v;
  126. cin >> u >> v;
  127. ll dist = fenw.get(tin[u]) + fenw.get(tin[v]) - 2 * fenw.get(tin[lca(u, v)]);
  128. cout << dist << '\n';
  129. }
  130. }
  131. }
Success #stdin #stdout 0.01s 22860KB
stdin
5
1 2 3
1 3 6
1 4 9
4 5 10
4
2 2 3
2 1 5
1 3 1
2 1 5
stdout
9
19
11