Use this to learn the idea, then write your own version.
1class LazySegmentTree {2 public:3 explicit LazySegmentTree(int n) : n(n), tree(4 * n), lazy(4 * n) {}4 5 6 void addRange(int l, int r, int val) {7 addRange(0, 0, n - 1, l, r, val);8 }9 10 11 int query(int i) {12 return query(0, 0, n - 1, i);13 }14 15 private:16 const int n; 17 vector<int> tree; 18 vector<int> lazy; 19 20 void push(int treeIndex, int lo, int hi) {21 if (lazy[treeIndex] == 0)22 return;23 tree[treeIndex] += lazy[treeIndex];24 if (lo != hi) {25 lazy[2 * treeIndex + 1] += lazy[treeIndex];26 lazy[2 * treeIndex + 2] += lazy[treeIndex];27 }28 lazy[treeIndex] = 0;29 }30 31 void addRange(int treeIndex, int lo, int hi, int l, int r, int val) {32 push(treeIndex, lo, hi);33 if (r < lo || l > hi) 34 return;35 if (l <= lo && hi <= r) { 36 lazy[treeIndex] += val;37 push(treeIndex, lo, hi);38 return;39 }40 const int mid = (lo + hi) / 2;41 addRange(2 * treeIndex + 1, lo, mid, l, r, val);42 addRange(2 * treeIndex + 2, mid + 1, hi, l, r, val);43 }44 45 int query(int treeIndex, int lo, int hi, int i) {46 push(treeIndex, lo, hi);47 if (lo == hi)48 return tree[treeIndex];49 const int mid = (lo + hi) / 2;50 if (i <= mid)51 return query(2 * treeIndex + 1, lo, mid, i);52 return query(2 * treeIndex + 2, mid + 1, hi, i);53 }54};55 56class Solution {57 public:58 vector<int> treeQueries(int n, vector<vector<int>>& edges,59 vector<vector<int>>& queries) {60 LazySegmentTree tree(n);61 vector<int> ans;62 vector<vector<pair<int, int>>> graph(n + 1);63 map<pair<int, int>, int> edgeWeights;64 65 for (const vector<int>& edge : edges) {66 const int u = edge[0];67 const int v = edge[1];68 const int w = edge[2];69 graph[u].emplace_back(v, w);70 graph[v].emplace_back(u, w);71 edgeWeights[{min(u, v), max(u, v)}] = w;72 }73 74 75 vector<int> inTime(n + 1);76 vector<int> outTime(n + 1);77 vector<int> dist(n + 1);78 vector<int> parent(n + 1);79 int time = 0;80 81 dfs(graph, 1, -1, time, inTime, outTime, dist, parent);82 83 for (int i = 1; i <= n; ++i)84 tree.addRange(inTime[i], inTime[i], dist[i]);85 86 for (const vector<int>& query : queries) {87 const int type = query[0];88 if (type == 1) {89 const int u = query[1];90 const int v = query[2];91 const int newWeight = query[3];92 const auto key = pair<int, int>{min(u, v), max(u, v)};93 const int oldWeight = edgeWeights[key];94 const int delta = newWeight - oldWeight;95 edgeWeights[key] = newWeight;96 97 const int child = (parent[v] == u) ? v : u;98 tree.addRange(inTime[child], outTime[child], delta);99 } else {100 const int x = query[1];101 ans.push_back(tree.query(inTime[x]));102 }103 }104 105 return ans;106 }107 108 private:109 void dfs(const vector<vector<pair<int, int>>>& graph, int u, int prev,110 int& time, vector<int>& inTime, vector<int>& outTime,111 vector<int>& dist, vector<int>& parent) {112 inTime[u] = time++;113 for (const auto& [v, w] : graph[u]) {114 if (v == prev)115 continue;116 dist[v] = dist[u] + w;117 parent[v] = u;118 dfs(graph, v, u, time, inTime, outTime, dist, parent);119 }120 outTime[u] = time - 1;121 }122};123