Expectations sky-high Gym - 102020E(树形dp)

https://vjudge.net/problem/Gym-102020E
先跑出一个点的值
然后用树形dp可推出其他所有点

ll num[maxn], sum[maxn], ans[maxn];

inline ll qpow(ll a, ll b) {
	ll res = 1;
	while (b) {
		if (b & 1)	res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}

inline ll qmod(ll a) {
	while (a >= mod)	a -= mod;
	return a;
}

vector<int> g[maxn];
void dfs1(int now, int fa) {
	num[now] = 1; sum[now] = 0;
	for (auto v : g[now]) {
		if (v == fa)	continue;
		dfs1(v, now);
		num[now] = qmod(num[now] + num[v]);
		sum[now] = qmod(sum[now] + sum[v] + num[v]);
	}
}

void dfs2(int now, int fa, int &n) {
	if (now != 1) ans[now] = qmod(n - num[now] + ans[fa] - num[now] + mod);
	for (auto v : g[now]) {
		if (v == fa)	continue;
		dfs2(v, now, n);
	}
}

signed main() {
	int n; scanf("%lld", &n);
	for (int i = 0; i < n - 1; ++i) {
		int u, v; scanf("%lld %lld", &u, &v);
		g[u].push_back(v); g[v].push_back(u);
	}
	dfs1(1, 1);
	ans[1] = sum[1];
	dfs2(1, 1, n);
	ll tot = 0;
	for (int i = 1; i <= n; ++i)	tot = qmod(tot + ans[i]);
	printf("%lld\n", tot * qpow(n * (n + 1) % mod, mod - 2) % mod);
	return 0;
}

posted @ 2021-03-06 22:19  wansheking  阅读(45)  评论(0)    收藏  举报