1 条题解

  • 0
    @ 2026-5-18 17:28:18

    D. Tree Jumps 详细题解

    问题理解

    我们有一棵以 11 为根的有根树,每个顶点 vv 的距离 dvd_v 定义为从根到 vv 的边数(根的距离为 00)。

    初始时棋子在根节点 11。每次操作可以将棋子从当前节点 vv 移动到某个节点 uu,满足 du=dv+1d_u = d_v + 1(即必须往下一层走),并且:

    • 如果 vv 是根节点,可以跳到下一层的任意节点
    • 如果 vv 不是根节点,则 uu 不能vv 的邻居(即不能是 vv 的父节点或子节点)

    注意:由于 du=dv+1d_u = d_v + 1uu 只能是 vv 的孩子节点或下一层的其他非孩子节点。但“不能是邻居”这个条件禁止跳到孩子节点(因为孩子是邻居),所以当 vv 不是根时,只能跳到下一层中不是自己孩子的节点

    一个顶点序列被称为有效,如果存在一种移动方式,使得棋子按顺序访问序列中的所有顶点(且只访问这些顶点,不能多也不能少)。

    求所有有效序列的数量,对 998244353998244353 取模。


    关键观察

    1. 序列必须从根开始

    因为棋子初始在根,且只能向下走(du=dv+1d_u = d_v + 1),所以任何有效序列的第一个顶点必须是根 11

    2. 序列中顶点的深度严格递增

    每次操作深度 +1+1,所以序列中顶点的深度必须严格递增:dv1<dv2<d_{v_1} < d_{v_2} < \dots
    因此,一个有效序列对应一条从根出发的“路径”,但这条路径不一定是树上的连续路径,因为可以跳到非孩子节点。

    3. 移动规则的本质

    设当前在深度 ii 的节点 vv,要跳到深度 i+1i+1 的节点 uu

    • 如果 i=0i = 0(即 vv 是根):可以跳到深度 11任意节点
    • 如果 i1i \ge 1:可以跳到深度 i+1i+1除了 vv 的孩子以外的任意节点

    换句话说,从深度 ii 的一个节点出发,能够到达的深度 i+1i+1 节点集合 = 整个深度 i+1i+1 的节点集合,减去该节点的孩子集合(当 i1i \ge 1 时)。


    动态规划思路

    dpvdp_v 表示以顶点 vv 结尾的有效序列的数量。

    那么答案就是 vdpv\sum_{v} dp_v

    边界条件

    dp1=1dp_1 = 1,因为序列 [1][1] 是有效的。

    转移方程

    对于非根节点 vv(深度 dv=i1d_v = i \ge 1),考虑它的所有可能前驱节点 pp(深度为 i1i-1 的节点),使得从 pp 可以合法地跳到 vv

    pp 跳到 vv 合法的条件是:

    • 如果 i1=0i-1 = 0(即 pp 是根):总是合法
    • 如果 i11i-1 \ge 1:需要 vv 不是 pp 的孩子

    所以:

    $$dp_v = \sum_{p \in \text{depth } i-1} [\text{可以从 } p \text{ 跳到 } v] \cdot dp_p $$

    Si1S_{i-1} 表示深度 i1i-1 的所有节点,totali1=pSi1dpptotal_{i-1} = \sum_{p \in S_{i-1}} dp_p

    那么:

    • 如果 i1=0i-1 = 0(即 i=1i=1):dpv=total0=1dp_v = total_0 = 1(因为深度 00 只有根,dp1=1dp_1=1
    • 如果 i11i-1 \ge 1:$dp_v = total_{i-1} - \sum_{p \text{ 是 } v \text{ 的父节点}} dp_p$

    注意:一个节点 vv 的父节点是唯一的,设为 f(v)f(v)。所以 $\sum_{p \text{ 是 } v \text{ 的父节点}} dp_p = dp_{f(v)}$。

    因此,对于深度 i2i \ge 2 的节点 vv

    dpv=totali1dpf(v)dp_v = total_{i-1} - dp_{f(v)}

    其中 totali1=u:du=i1dputotal_{i-1} = \sum_{u: d_u = i-1} dp_u


    算法步骤

    1. 读入树,计算每个节点的深度 dvd_v
    2. 按深度分组,得到每层的节点列表 vs[d]
    3. 初始化:
      • dp[1]=1dp[1] = 1
      • total[0]=1total[0] = 1
    4. 按深度 ii11 到最大深度遍历:
      • 对于当前层的每个节点 vv
        • 如果 i=1i = 1vv 在深度 11):dp[v]=total[0]=1dp[v] = total[0] = 1
        • 如果 i2i \ge 2dp[v]=total[i1]dp[parent[v]]dp[v] = total[i-1] - dp[parent[v]](模意义下)
      • 计算 total[i]=vvs[i]dp[v]total[i] = \sum_{v \in vs[i]} dp[v]
    5. 答案 = itotal[i]\sum_{i} total[i](即所有 dpdp 之和)

    正确性证明

    归纳法:假设对于深度 i1i-1 的所有节点,dpdp 值已正确计算(表示以该节点结尾的有效序列数)。

    对于深度 ii 的节点 vv,所有以 vv 结尾的有效序列,去掉最后一个节点 vv 后,得到的是一个以某个深度 i1i-1 节点 pp 结尾的有效序列,并且从 pp 可以合法跳到 vv

    • 如果 i=1i=1pp 只能是根,且根可以跳到任意深度 11 节点,所以 dpv=total0=1dp_v = total_0 = 1
    • 如果 i2i \ge 2pp 可以是深度 i1i-1 的任意节点,除了 vv 的父节点(因为不能从父节点跳到子节点)。所以 dpv=totali1dpparent(v)dp_v = total_{i-1} - dp_{parent(v)}

    因此转移正确。


    复杂度分析

    • 计算深度:O(n)O(n)
    • 按深度分组:O(n)O(n)
    • 每层遍历:O(n)O(n)
    • 总时间复杂度 O(n)O(n),每个测试用例
    • 所有测试用例 nn 之和 3×105\le 3\times10^5,完全可行

    示例验证(以第一个样例为例)

    树结构:n=4n=4,父节点列表 p2=1,p3=2,p4=1p_2=1, p_3=2, p_4=1
    深度:d1=0d_1=0d2=1d_2=1d3=2d_3=2d4=1d_4=1

    • 深度 00vs[0]={1}vs[0] = \{1\}dp[1]=1dp[1]=1total[0]=1total[0]=1
    • 深度 11vs[1]={2,4}vs[1] = \{2,4\}
      • dp[2]=total[0]=1dp[2] = total[0] = 1
      • dp[4]=total[0]=1dp[4] = total[0] = 1
      • total[1]=1+1=2total[1] = 1+1=2
    • 深度 22vs[2]={3}vs[2] = \{3\},父节点 parent[3]=2parent[3]=2
      • dp[3]=total[1]dp[2]=21=1dp[3] = total[1] - dp[2] = 2 - 1 = 1
      • total[2]=1total[2] = 1

    答案 = total[0]+total[1]+total[2]=1+2+1=4total[0]+total[1]+total[2] = 1+2+1 = 4,匹配输出。


    总结

    本题的核心是:

    1. 观察到移动规则等价于:从深度 ii 的非根节点,可以跳到下一层的任意节点,除了自己的子节点
    2. 使用按深度分层的 DP,转移时用“当前层总和减去父节点贡献”
    3. 避免 O(n2)O(n^2) 的枚举,通过维护 total[i]total[i] 实现 O(n)O(n) 转移

    这种“总合法前驱减去非法前驱”的技巧在树形 DP 中非常常见。

    • 1

    信息

    ID
    7214
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者