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;
}
posted @ 2023-08-22 09:19  5k_sync_closer  阅读(3)  评论(0编辑  收藏  举报  来源