AGC009D - Uninity 题解
给定 个点的树,求其点分树的最小可能的深度。
。
第一个想法是,直接枚举分治中心,然后分裂成若干个连通块,递归下去。这就是个状态数是连通块子图数量的 DP,模拟赛可能能写个记忆化骗个分啥的,正解就不用想了。
我们发现这样正常做完全没思路。我们必须转化,我们必将转化。
intended 的考虑是:给每个点标号 ,代表它在点分树上的深度,求所有合法标号方案的最大标号的最小值。对如何想到这个的,我有两点理解:
- 换贡献体。直接考虑以点的深度序列为贡献体,自然就能想到标号。
- 或者直接认为对节点进行标号就是一种常规的套路,也不是不行,类似于染色法。
我们来考察一个标号方案的合法性的判定。考虑堆砌必要条件。对于两个点 ,它们之间的链上肯定有一个点,是第一次分裂它们的点,也就是在点分树上的 LCA。如果 ,那完全可以令深度小的那个当 LCA,没什么结论;而如果 , 之间的任何一个都不可能是 LCA,那只能是链中间的。那么就得到了一个看上去挺强的必要条件:对所有 ,它们的简单路径上必须存在 满足 。
我们来试图证明其充分性:尝试根据 还原点分树。首先找到 的 ,它显然最多有一个(因为没有小于 的标号),而如果没有的话一定不优,所以 存在且唯一。然后归纳到分裂的若干连通块,只不过最小值为 。就这样递归下去,每递归一层最小值就增加 ,一定能构造出点分树。
现在我们开始全身心最小化合法标号方案的最大标号。考虑树形 DP 的话,需要记录子树对外界的影响:只需要用一个 mask,记录从根往下的所有前缀最小值。注意到由于答案是 级别,所以这个 mask 只有 。但仍然无济于事,先不说 DP 的转移非常复杂,状态数本身就要 了。
容易想到二分答案 ,限制最大标号不超过 ,这样问题看似直接降了一个维度,而只付出了 的代价。我们还是要记录一个 mask,而 DP 值变成了 bool
表示是否可行。看起来还是没什么用。
我们注意到:在二分答案之前,叶子处的决策是不确定的;而如今确定了 ,那么叶子肯定贪心地选 ,留给上面最多的选择空间。至少在叶子处,DP 的决策是唯一的,局部退化为了贪心。而如果非叶节点的决策也是唯一的,整个 DP 就完全退化为了贪心,不需要再以 mask 为状态,直接记录贪心得到的 mask 即可。这就是说,贪心本质上是每处决策都唯一的退化版 DP。
于是我们来具体看看非叶节点的转移。假设所有儿子的 mask 已经确定,设为 ,如果此时能够找到 的严格最优解,就得到了贪心。首先,对于同时出现在两个 里的 ,必须要有 ,这就得到了一个限制 。然后再考虑 自身与子树里的标号也不能违反条件,具体来说就是必须有 。这样 处新的 mask 就是 。
我们能比较选不同的合法的 时,得到的 的严格优劣吗?直觉告诉我们,类似于叶子, 应当越大越好,这样看似能留给上面最多的选择空间。稍加思考,发现八九不离十。考虑 为 今后第一个可能可选的标号,我们发现 永远不可能再被选了,因为想要将某个数从 中清除必须选择一个更小的不在 里的数,而作为前缀连续段这是不可能的。这就启发我们比较两个 的字典序:对于最小的 ,满足 ,不妨设 ;当 作为儿子时,不妨设其他 都不包含 (否则选 时 ,一定寄了, 不劣),那么当选择 时我们有令 的权利,显然后续得到的新 优于选择 时的任意决策。
这就是说, 作为二进制数,字典序越小越好,也就是 应当取合法的最大值。这样决策永远是唯一的,我们成功造出了一个贪心算法。时间复杂度 ,代码。
进一步观察这个贪心,发现对不同的 仿佛就是将 们平移了一样,而我们要求的 正是最小的使得各 不渗透到负下标的偏移量。容易想到记录各子树的最小 以及对应的 ,转移时按最大偏移量进行对齐,再根据需求增大偏移量即可。时间复杂度 ,代码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-05-25 sb 错误