1 条题解
-
0
#include <bits/stdc++.h> using namespace std; #define eb emplace_back #define LL long long template <typename T> void qr(T& x) { char c = getchar(); x = 0; int f = 1; for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + (c - '0'); x *= f; } template <typename T> void qw(T x) { if (x < 0) putchar('-'), x = -x; if (x / 10) qw(x / 10); putchar(x % 10 + '0'); } const int N = 1e6 + 10; vector<int> G[N]; int n; LL v[N]; int fa[N], siz[N], dep[N], son[N]; void dfs1(int x, int xfa) { fa[x] = xfa; dep[x] = dep[xfa] + 1; siz[x] = 1; son[x] = 0; for (int y : G[x]) if (y != xfa) { dfs1(y, x); siz[x] += siz[y]; if (siz[y] > siz[son[x]]) son[x] = y; } } int tsp, dfn[N], top[N]; void dfs2(int x, int tp) { dfn[x] = ++tsp; top[x] = tp; if (son[x]) dfs2(son[x], tp); for (int y : G[x]) if (y != son[x] && y != fa[x]) dfs2(y, y); } int LCA(int x, int y) { for (; top[x] != top[y]; x = fa[top[x]]) if (dep[top[x]] < dep[top[y]]) swap(x, y); return dep[x] < dep[y] ? x : y; } LL c1[N], c2[N]; void add(LL c[], int x, LL k) { if (x == 0) return; for (; x <= n; x += x & -x) c[x] += k; } LL sum(LL c[], int x) { LL res = 0; for (; x >= 1; x -= x & -x) res += c[x]; return res; } LL getsum(int x) { return sum(c1, dfn[x]) * dep[x] + sum(c2, dfn[x]); } int main() { int m, rt; qr(n); qr(m); qr(rt); for (int i = 1; i <= n; i++) qr(v[i]); for (int i = 1, x, y; i < n; i++) qr(x), qr(y), G[x].eb(y), G[y].eb(x); dep[0] = 0; dfs1(rt, 0); tsp = 0; dfs2(rt, rt); for (int i = n; i >= 1; i--) { int l = dfn[i], r = dfn[i] + siz[i] - 1; add(c2, l, v[i]); add(c2, r + 1, -v[i]); } while (m--) { int op; scanf("%d", &op); if (op == 1) // 1 x k,表示将结点 x 的权值增加 k { int x; LL k; qr(x); qr(k); int l = dfn[x], r = dfn[x] + siz[x] - 1; add(c2, l, k); add(c2, r + 1, -k); } else if (op == 2) // 2 x k,表示将 x 的子树上所有结点的权值增加 k { int x; LL k; qr(x); qr(k); int l = dfn[x], r = dfn[x] + siz[x] - 1; add(c1, l, k); add(c1, r + 1, -k); add(c2, l, -k * (dep[x] - 1)); add(c2, r + 1, k * (dep[x] - 1)); } else // 3 x y,表示求「结点 x 到结点 y 的简单路径」上所有结点的权值之和 { int x, y; qr(x); qr(y); int lca = LCA(x, y); qw(getsum(x) + getsum(y) - getsum(lca) - getsum(fa[lca])); printf("\n"); } } return 0; }
- 1
信息
- ID
- 276
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 7
- 标签
- 递交数
- 52
- 已通过
- 12
- 上传者