1 条题解
-
0
题意理解
给定一棵 ( n ) 个节点的有根树,满足 ( 1 \sim n ) 是一个 DFS 序(即按编号顺序深度优先遍历可达)。
初始所有节点未崩坏。
每天进行如下操作:- 选择一个未崩坏节点 ( u ) 探索。
- 探索后,( u ) 及其子树全部崩坏。
- 同时,由于力量枯竭,第 ( n-i+1 ) 号节点若未崩坏,则崩坏(( i ) 为当前天数)。
要求探索序列满足:
- 恰好探索 ( i ) 天。
- 最后一次探索的是根节点 1。
求对每个 ( i \in [1,n] ) 的方案数(模 998244353)。
关键观察
-
DFS 序性质
由于编号顺序就是 DFS 序,所以对于任意节点,其子树编号连续(编号 ( [u, u+size_u-1] ))。
探索节点 ( u ) 会直接崩坏其整个子树。 -
崩坏规则
- 主动崩坏:探索节点 ( u ) → 崩坏 ( u ) 的子树区间。
- 被动崩坏:第 ( i ) 天结束 → 崩坏节点 ( n-i+1 )(若未崩坏)。
被动崩坏每天固定一个节点,从后往前(( n, n-1, \dots ))。
-
问题转化
将探索序列看作一个节点集合,按探索顺序满足:- 最后一个是根节点 1。
- 若探索节点 ( u ),则其子树中节点不能再被探索(已崩坏),且被动崩坏不会影响已探索节点。
- 被动崩坏从后往前,相当于每天有一个“强制崩坏节点”,需要确保在强制崩坏时该节点尚未被探索(否则已崩坏)。
实际上,强制崩坏相当于在当天结束时,若某节点未被主动崩坏,则它自动崩坏。
-
状态设计
定义 ( f[i][j][k] ) 表示考虑从第 ( i ) 天开始(倒序处理),已经探索了 ( j ) 个节点,且这些节点的最小 DFS 序编号为 ( k )。
为什么倒序?因为被动崩坏从后往前,倒序处理便于匹配强制崩坏节点。 -
转移分析
- 不选择第 ( i ) 天探索:直接继承 ( f[i+1][j][k] )。
- 选择第 ( i ) 天探索某个节点:探索节点 ( u ) 需满足:
- ( u ) 未被崩坏(即其编号不在已探索节点的子树中)。
- 探索后崩坏 ( u ) 的子树,更新已探索集合。
- 同时,第 ( i ) 天结束时会强制崩坏节点 ( n-i+1 ),需确保该节点在探索前未被崩坏(或被探索主动崩坏)。
-
子树贡献合并
预处理 ( h[u][l] ) 表示在节点 ( u ) 的子树中选择 ( l ) 个节点探索的方案数(满足子树内探索顺序合法)。
这可以通过树形 DP 合并子节点得到,用组合数处理顺序。 -
最终计算
倒序 DP 完成后,( f[1][i][i] ) 表示探索 ( i ) 天且最后一个探索节点编号为 ( i ) 的方案数(因为最小编号为 ( i ) 意味着所有探索节点编号 ≥ i)。
但要求最后一个探索的是根节点 1,因此需要筛选。
算法流程
- 预处理组合数 ( C[n][n] )。
- 读入树,由于 DFS 序性质,父子关系可由编号大小确定(编号小的为父节点)。
- 树形 DP 计算 ( h[u][l] ):
- ( g[u][l] ) 表示 ( u ) 子树中选 ( l ) 个节点探索的方案数。
- 合并子节点时,用组合数合并顺序。
- ( h[u][l] = g[u][l-1] )(因为 ( u ) 本身必须被选)。
- 倒序 DP:
- 状态 ( f[i][j][k] ) 表示从第 ( i ) 天开始倒序考虑,已选 ( j ) 个节点,最小编号为 ( k )。
- 转移分三种:
a. 第 ( i ) 天不探索 → 继承。
b. 第 ( i ) 天探索某个编号 > k 的节点 → 更新最小编号。
c. 第 ( i ) 天探索节点 ( u ) 且 ( u ) 的子树与已选集合有重叠 → 通过 ( h[u][l] ) 合并子树贡献。
- 输出答案:
- ( ans[i] = f[1][i][i] - f[2][i][i] )(差分得到最后一个探索节点是 1 的方案数)。
复杂度分析
状态数 ( O(n^3) ),转移 ( O(n^2) ),总复杂度 ( O(n^5) )?
但实际常数小,且 ( n \leq 80 ),可接受。算法标签
- 树形 DP
- 计数 DP
- 倒序动态规划
- 组合数学
- DFS 序性质
- 1
信息
- ID
- 5770
- 时间
- 2500ms
- 内存
- 768MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者