[Agc029E]Wandering TKHS_树形dp_树上差分
Wandering TKHS
题目链接:https://atcoder.jp/contests/agc029/tasks/agc029_e
数据范围:略。
题解:
好神啊
Orz司队
https://www.cnblogs.com/ivorysi/p/10157002.html
代码:
#include <bits/stdc++.h> #define N 300010 using namespace std; char *p1, *p2, buf[100000]; #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) int rd() { int x = 0, f = 1; char c = nc(); while (c < 48) { if (c == '-') f = -1; c = nc(); } while (c > 47) { x = (((x << 2) + x) << 1) + (c ^ 48), c = nc(); } return x * f; } int head[N], to[N << 1], nxt[N << 1], tot; inline void add(int x, int y) { to[ ++ tot] = y; nxt[tot] = head[x]; head[x] = tot; } int mx[N], sz[N], d[N], c[N], son[N]; void calc(int p, int fa, int v) { son[p] = 1; for (int i = head[p]; i; i = nxt[i]) { if (to[i] != fa && to[i] < v) { calc(to[i], p, v); son[p] += son[to[i]]; } } } void dfs(int p, int fa) { mx[p] = max(mx[fa], p); sz[p] = 1; for (int i = head[p]; i; i = nxt[i]) { if (to[i] != fa) { dfs(to[i], p); sz[p] += sz[to[i]], d[p] += d[to[i]]; } } if (mx[p] == p) { calc(p, fa, mx[fa]); d[p] = -sz[p]; } if (mx[fa] == fa) { d[p] += sz[p]; } } void dfs2(int p, int fa) { if (fa) { if (mx[p] == p) { c[p] += son[p]; } else if (mx[fa] == fa) { c[p] -= son[p], c[p] += d[p]; } c[p] += c[fa]; } for (int i = head[p]; i; i = nxt[i]) { if (to[i] != fa) { dfs2(to[i], p); } } } int main() { int n = rd(); for (int i = 1; i < n; i ++ ) { int x = rd(), y = rd(); add(x, y), add(y, x); } dfs(1,0), dfs2(1,0); for (int i = 2; i <= n; i ++ ) printf("%d ", c[i]); return 0; }
| 欢迎来原网站坐坐! >原文链接<