CF1060E 题解

前言

题目传送门!

更好的阅读体验?

提供一种更加麻烦的换根 DP 写法。

思路

手玩样例。发现一个性质:原图上距离为 \(w\) 的两个点,在新图上的距离是 \(\lfloor\dfrac{w}{2}\rfloor\)

于是题目就是求 \(\sum\limits_{u=1}^n\sum\limits_{v=1}^n\lfloor\dfrac{dis(u, v)}{2}\rfloor\),很容易想到求出每一个 \(\sum\limits_{v=1}^n\lfloor\dfrac{dis(u, v)}{2}\rfloor\) 后求和即为答案。

这种形式就是换根 DP。

维护 \(siz_{u, i}\)\(i \in \{0, 1\}\))表示 \(u\) 的子树到 \(u\)原距离为奇数(或偶数)的点的数量。

同样地,\(sum_u\) 统计 \(u\) 的子树到 \(u\)新距离的点的数量。

于是就有:

\[siz_{u, 0} = 1 + \sum\limits_{v \in son_u} siz_{v, 1} \]

\[siz_{u, 1} = \sum\limits_{v \in son_u} siz_{v, 0} \]

\[sum_u = 1 + \sum\limits_{v \in son_u} (sum_v + siz_{v, 0}) \]

状态很套路所以就不解释了。

然后就是换根。不妨设当前以 \(1\) 为根,于是 \(ans_u\) 表示以 \(u\) 为根的时候的答案。

接下来就是换根:

\[ans_u = \begin{cases} 1 & u = 1 \\ ans_{fa} + siz_{1, k} - siz_{u, 1} - siz_{u, 0} & \text{otherwise} \end{cases}\]

其中 \(k\) 表示 \(dep_u \mod 2\)

解释一下。对于 \(u\)

  • 所有到 \(u\) 为奇数的点的距离都要加 \(1\),一共有 \((siz_{1, k} - siz_{u, 1})\) 个这种点。
  • 所有到 \(u\) 为偶数的点的距离都要减 \(1\),一共有 \(siz_{u, 0}\) 个这种点。

答案即为 \(\lfloor\dfrac{\scriptsize\sum\limits_{i=1}^n ans_i}{2}\rfloor\)

代码

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
struct Edge {int now, nxt;} e[N << 1];
int head[N], cur;
void add(int u, int v)
{
	e[++cur].now = v, e[cur].nxt = head[u];
	head[u] = cur;
}
ll sum[N], siz[N][2];
void dfs(int u, int fa)
{
	siz[u][0] = 1;
	for (int i = head[u]; i; i = e[i].nxt)
	{
		int v = e[i].now;
		if (v == fa) continue;
		dfs(v, u);
		siz[u][0] += siz[v][1], siz[u][1] += siz[v][0];
		sum[u] += (sum[v] + siz[v][0]);
	}
}
ll ans[N];
void DFS(int u, int fa, int dep)
{
	for (int i = head[u]; i; i = e[i].nxt)
	{
		int v = e[i].now;
		if (v == fa) continue;
		ans[v] = ans[u] + siz[1][dep & 1] - siz[v][1] - siz[v][0];
		DFS(v, u, dep + 1);
	}
}
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v), add(v, u);
	}
	dfs(1, 0), ans[1] = sum[1], DFS(1, 0, 0);
	ll zlt = 0;
	for (int i = 1; i <= n; i++) zlt += ans[i];
	cout << zlt / 2;
	return 0;
}

希望能帮助到大家!

posted @ 2023-03-19 18:43  liangbowen  阅读(16)  评论(0编辑  收藏  举报