树形 dp 总结 2

P6419(树的中心 dp 套路)

不难发现,司机总是进入一个子树然后原路返回,最后一个子树除外。

对于这种问题,我们不难想到树的中心的类似套路,维护 \(down_i,up_i,len1_i,len2_i\) 表示向子树内走的最少时间/子树外的最少时间/子树内的最长链/子树内的次长链。转移是套路的,注意特判子树内和子树外没人的情况即可。

QOJ 10268(树的直径性质)

看到这个 \(\max\),引导我们向树的直径思考。

我们也可以定义一个点集 \(S\) 的“直径”为 \(A_i\),既然题目要求 \(A_i\) 不同的方案数,不妨考虑什么唯一决定了 \(A_i\)

我们知道,当直径长度为偶数时,中心有且仅有一个;当直径长度为奇数时,中心有两个且相邻。我们不妨把第二种情形的“中心”看作连接两个中心的那条边。设半径(字面意思,直径的一半)为 \(r\),“中心”为 \(c\),易知 \(A_i=dis_{c,i}+r\),这表明 \(c,r\) 唯一决定了 \(A_i\)(尽管可能存在 \(c_i \neq c_j,r_i \neq r_j\) 使得 \(A_i = A_j\),但我们只需要整个数组有一处不同就算不同)。

这样,问题转化为求 \(c,r\) 的方案数,考虑固定 \(c\) 计算 \(r\) 的方案然后求和。不难发现 \(r\) 最大可以取到子树内的次长链(如果最长的话另一半就没有了,次长链可以取出最长链的一部分来组成直径),所以这就可以再次使用上一题的 dp 思路去做了。

别看我几段话就讲完了,这里面的三个转化还是很精妙的。

CF916E(抓住不变量)

全场最简单的。

如果没有操作一显然线段树维护 dfn 序列即可。

手玩一下可以发现换根完了之后有些节点的子树不发生变化,具体而言,他们是新根在原树上的非祖先。

这样我们可以进行讨论:

  • 对于 \(u=root\),显然对整棵树操作即可。

  • 对于 \(u\) 不是 \(root\) 的祖先,则按原树操作即可。

  • 对于 \(u\)\(root\) 的祖先,显然我们发现只有 \(u\)\(u\) 上边的节点成为了 \(u\) 的子树,然而 \(son_u\) 下面的部分是一段连续区间,所以我们直接将 \([1,n]\) 砍掉 \([son_u,son_u+siz_{son_u}-1]\),对这两段区间操作即可。

是不是做完了?并非。还有一个问题是如何求出 lca,感性猜测一下可以发现,对于 \(u,v\)\(lca'(u,v)\)\(lca(u,v),lca(u,rt),lca(v,rt)\) 中深度最大的那个(\(lca\) 是原树上,\(lca'\) 是新树上),这个感受一下或者你分类讨论证明都行,应该很好理解。

然后我们解决了这个 *2400,实现比前两题好写一万倍。

posted @ 2026-08-27 00:49  _KidA  阅读(5)  评论(0)    收藏  举报