CF1060E Sergey and Subway 题解
令 $\text{subtree}(x)$ 表示 $x$ 子树,$\text{fa}(x)$ 表示 $x$ 的父亲,$d(i,j)$ 表示 $i$ 到 $j$ 的距离。
答案等于 $\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n\left\lceil\dfrac{d(i,j)}2\right\rceil$,于是随便怎么求一下,比如换根 DP。
设 $f_i=\sum\limits_{j\in\text{subtree}(i)}\left\lceil\dfrac{d(i,j)}2\right\rceil,s_i=\sum\limits_{j\in\text{subtree}(i)}[d(i,j)\equiv 0\pmod 2]$,
则有 $f_u=\sum\limits_{v\in\text{son}(u)}f_v+s_v$(所有到 $v$ 距离为偶数的点到 $u$ 距离为奇数,贡献加一),
$s_u=1+\sum\limits_{v\in\text{son}(u)}\text{size}_v-s_v$(所有到 $v$ 距离为奇数的点到 $u$ 距离为偶数)。
设 $g_i=\sum\limits_{j=1}^n\left\lceil\dfrac{d(i,j)}2\right\rceil,t_i=\sum\limits_{j=1}^n[d(i,j)\equiv 0\pmod 2]$,
则有 $g_v=f_v+(g_{\text{fa}(v)}-f_v-s_v)+(t_{\text{fa}(v)}-\text{size}_v+s_v)=g_{\text{fa}(v)}+t_{\text{fa}(v)}-\text{size}_v,t_v=n-t_{\text{fa}(v)}$。
#include <cstdio>
#define int long long
struct E
{
int v, t;
} e[1000050];
int n, c, q, S[1000050], f[1000050], s[1000050], g[1000050], t[1000050], h[1000050];
void A(int u, int v)
{
e[++c] = {v, h[u]};
h[u] = c;
}
void F(int u, int k)
{
S[u] = s[u] = 1;
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
F(v, u), S[u] += S[v], s[u] += S[v] - s[v], f[u] += f[v] + s[v];
}
void G(int u, int k)
{
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
t[v] = n - t[u], g[v] = g[u] + t[u] - S[v], G(v, u);
}
signed main()
{
scanf("%lld", &n);
for (int i = 1, u, v; i < n; ++i)
scanf("%lld%lld", &u, &v), A(u, v), A(v, u);
F(1, 0);
g[1] = f[1];
t[1] = s[1];
G(1, 0);
for (int i = 1; i <= n; ++i)
q += g[i];
printf("%lld", q >> 1);
return 0;
}