树形 dp 总结

contest

A(考虑影响 + 分类讨论)

首先,我们可以发现 \(c_i=0\) 这个限制很令人火大。

观察到题目中只存在子树内的操作,因此想到祖先节点的操作会影响当前节点。具体而言,我们发现当祖先节点操作了至少一次时,我们总能通过调整操作顺序使得当前节点 \(c_i=0\)。但如果一次都没有呢?所以,只有 \(c'_i=1\) 时,当前节点 \(i\) 才能操作。

于是,定义 \(dp_{i,0/1}\) 表示当前节点 \(i\) 的祖先节点是否操作的方案数。对于祖先操作过的情况,有 \(dp_{i,1}=2 \times \prod dp_{nxt,1}\)(操作和不操作都合法);对于没有操作过的,如果 \(c'_i=0\) 那就是 \(\prod dp_{nxt,0}\),否则还得加上 \(\prod dp_{nxt,1}\)

B(根节点路径问题转化为子树问题)

考虑设 \(x_i\) 表示点 \(i\) 被翻转了几次,则节点 \(i\) 翻转量 \(y_i\) 是其子树内所有节点 \(x_i\) 的异或和,目标要求 \(a_i \oplus y_i =0\),即 \(y_i = a_i\)

完成这个转化之后,我们考虑 dp。观察到有如下递推关系:

\[y_i = x_i \oplus \left( \oplus_{nxt \in son_i} y_{nxt} \right) \]

\(y_i\) 换成 \(a_i\) 之后,我们发现 \(x_i\) 是唯一确定的,于是我们就这样计算即可,\(ans=\sum x_i\)

至于修改,我们只需要修改当前节点和父节点即可。

C(手玩技巧)

首先,若一个点能使棋子走到黑点,则我们称之为“好点”。

不难发现以下结论:

  • 对于一个黑点,它本身就是“好点”;

  • 对于邻接点是黑点的点,它也是“好点”;

  • 而对于一对邻接点 \(u,v\),若 \(v\) 子树内有两个黑点,且它自己也是“好点”,则 \(u\) 也是“好点”(这个可以手玩得出,那两个黑点可以交替使用让棋子走过去)。

这样我们便可以换根 dp 了(这题不止考虑子树内,所以要换根)。

套路的令 \(dp_i\) 表示 \(i\) 是否为子树内的“好点”,\(f_i\) 则是否为全局“好点”,按上述三类情况转移即可。

posted @ 2026-08-24 22:58  _KidA  阅读(5)  评论(0)    收藏  举报