CF 传送门
AT 传送门
两题主要 Trick 相同。CF 的还多了一个小 trick。
给定一棵根节点为 的二叉树 ,你需要先保留一个包含 号节点的连通块,然后给每个点确定一个权值 ,使得对于每个点 都有其权值 大于等于其所有儿子的权值和 。
最后,你需要使得根节点权值为 ,求方案数,答案对 取模。
.
即 ,令 ,即 。注意到 ,且 与 一一对应,所以分配 相当于分配 。而如果选了固定 个点,分配 就是把 分给 个数,每个数 。这是经典结论,有 种分配方式。
于是下面的问题就是对于每个 ,求出有多少个 大小的包含 的连通块。
法一:普通树形 DP。 表示在 的子树内选 个点的方案数。转移方程 。因为每一对点的复杂度在其 LCA 处贡献 次,复杂度是 的。
法二:dfs 序 DP。 表示考虑 dfs 序 的结点选不选,共选了 个的方案数。转移方程 ,。复杂度 。
法三:FFT + 树剖优化法一。注意到法一 的形式是卷积,考虑使用 FFT 优化。转移方程为 。
但是直接上复杂度是 的,因为两个式子卷积 ,所以每一对点贡献的复杂度变成 了。
难道这个做法没有用吗?不,我们还有办法!上面做法的问题在于每个点会被使用太多次了。有什么办法是让一个点出现次数变少的?
树剖!我们进行重链剖分,仅在重链链顶处统计重链上所有的点和轻儿子的贡献。

如图。在重链链顶 处计算 ,可以一路分解下去到轻儿子。记相关的多项式为 ,要求的形式即为 ,而 的大小之和是 的。这种形式可以用分治 FFT 计算。

具体而言,我们在计算 时,先递归计算 和 部分。同时让这两部分额外返回 和 的值,则当前结果即为 ,用一次多项式加法和一次多项式乘法可以 做到。
分治 层,每层 合并。所以计算重链链顶多项式的复杂度是 的。(这里的 是所在重链轻子树大小之和)
所以一个结点在作为轻儿子时会贡献 的复杂度,每个结点贡献 次,总复杂度 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!