Untitled
unknown
c_cpp
a year ago
3.7 kB
6
Indexable
#include<bits/stdc++.h> #define ll long long #define ld long double #define fi first #define se second #define pii pair<int, int> #define pll pair<long long, long long> using namespace std; const int MAX = 3e5 + 5; vector<int> edges[MAX]; ll tree[MAX * 4]; int level[MAX]; int parent[MAX]; int reorder[MAX]; int heavy[MAX]; int subg_size[MAX]; int chain_top[MAX]; int dp[MAX][20]; int cnt = 0; void update(int idx, int left, int right, int a, ll val) { if (a < left || a > right) return; if (left == right) { tree[idx] = val; return; } int mid = (left + right) / 2; update(idx * 2, left, mid, a, val); update(idx * 2 + 1, mid + 1, right, a, val); tree[idx] = tree[idx * 2] + tree[idx * 2 + 1]; return; } ll query(int idx, int left, int right, int a, int b) { if (b < left || a > right) return 0; if (a <= left && b >= right) return tree[idx]; int mid = (left + right) / 2; return query(idx * 2, left, mid, a, b) + query(idx * 2 + 1, mid + 1, right, a, b); } void dfs(int a, int prev) { level[a] = level[prev] + 1; dp[a][0] = prev; for (int j = 1; j < 20; j++) dp[a][j] = dp[dp[a][j - 1]][j - 1]; for (auto e : edges[a]) { if (e == prev) continue; dfs(e, a); } return; } int lca(int a, int b) { if (level[a] < level[b]) swap(a, b); int diff = level[a] - level[b]; for (int j = 0; j < 20; j++) { if (diff & 1 << j) a = dp[a][j]; } if (a == b) return a; for (int j = 19; j >= 0; j--) { if (dp[a][j] == dp[b][j]) continue; a = dp[a][j]; b = dp[b][j]; } return dp[a][0]; } void dfs2(int a, int prev) { subg_size[a] = 1; parent[a] = prev; for (auto e : edges[a]) { if (e == prev) continue; dfs2(e, a); subg_size[a] += subg_size[e]; if (subg_size[heavy[a]] < subg_size[e]) heavy[a] = e; } return; } void dfs3(int a, int prev) { reorder[a] = ++cnt; if (!heavy[a]) return; dfs3(heavy[a], a); for (auto e : edges[a]) { if (e == prev || e == heavy[a]) continue; dfs3(e, a); } return; } void dfs4(int a, int prev) { for (auto e : edges[a]) { if (e == prev) continue; if (e == heavy[a]) chain_top[e] = chain_top[a]; else chain_top[e] = e; dfs4(e, a); } return; } ll calc(int a, int b, int n) { ll ans = query(1, 0, n, reorder[a], reorder[a]); while(a != b) { int nxt; if (chain_top[a] == a) nxt = parent[a]; else if (level[chain_top[a]] >= level[b]) nxt = chain_top[a]; else nxt = b; ans += query(1, 0, n, reorder[nxt], reorder[parent[a]]); a = nxt; } return ans; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, q, a, b, t; cin >> n >> q; vector<ll> v(n + 1); for (int i = 1; i <= n; i++) cin >> v[i]; for (int i = 0; i < n - 1; i++) { cin >> a >> b; edges[a].push_back(b); edges[b].push_back(a); } chain_top[1] = 1; dfs(1, 0); dfs2(1, 0); dfs3(1, 0); dfs4(1, 0); for (int i = 1; i <= n; i++) update(1, 0, n, reorder[i], v[i]); while(q--) { cin >> t >> a >> b; if (t == 1) { update(1, 0, n, reorder[a], b); } else { int c = lca(a, b); cout << calc(a, c, n) + calc(b, c, n) - query(1, 0, n, reorder[c], reorder[c]) << "\n"; } } return 0; }
Editor is loading...
Leave a Comment