1 条题解
-
0
文字教学
- 预处理树结构:先DFS一遍求出每个节点的父节点
fa。 - 统一统计操作:
- 操作1(子树加):用
a1[x]记录在x处的子树加标记。 - 操作2(邻域加):拆分为三部分统计:
a2_self[x]:给x自己加的总量;- 给
x父节点加的量直接计入a2_self[fa[x]]; a2_child[x]:给x所有子节点加的总量。
- 操作1(子树加):用
- 一次DFS更新:用变量
cur1传递操作1的子树增量,进入节点时累加a1[x],离开时减去;每个节点的最终增量 =cur1(操作1) +a2_self[x](给自己加的) +a2_child[fa[x]](父节点给子节点加的)。
代码
#include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; typedef long long ll; vector<int> adj[N]; int fa[N]; ll a[N], a1[N], a2_self[N], a2_child[N], ans[N]; void dfs1(int u, int p) { fa[u] = p; for (int v : adj[u]) { if (v != p) dfs1(v, u); } } void dfs2(int u, int p, ll cur1) { cur1 += a1[u]; ans[u] = a[u] + cur1 + a2_self[u]; if (p != 0) ans[u] += a2_child[p]; for (int v : adj[u]) { if (v != p) dfs2(v, u, cur1); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; for (int i = 1; i <= n; ++i) cin >> a[i]; for (int i = 0; i < n-1; ++i) { int x, y; cin >> x >> y; adj[x].push_back(y); adj[y].push_back(x); } dfs1(1, 0); int m; cin >> m; while (m--) { int p, x, y; cin >> p >> x >> y; if (p == 1) { a1[x] += y; } else { a2_self[x] += y; if (fa[x] != 0) a2_self[fa[x]] += y; a2_child[x] += y; } } dfs2(1, 0, 0); int q; cin >> q; while (q--) { int x; cin >> x; cout << ans[x] << '\n'; } return 0; } - 预处理树结构:先DFS一遍求出每个节点的父节点
- 1
信息
- ID
- 11166
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者
京公网安备 11011102002149号