【题解】AGC008F | 思维 统计技巧 换根 二次扫描
题意:给出一个 个点的树(边权为 )和集合 ,求有多少个点集 可以被表示为离 中的一个点 距离不超过 的点构成的集合(下文称为 的 级邻域)。
考虑 为所有点的特殊情况:
我们直接求每个点邻域的个数再求和,会算重一些点集,这种情况发生仅当这个邻域在某些方向“满了”,从而可以认为是向没满的方向移动一些并把这个点当作邻域的中心。
如下图中的黑色点集既可以表示为 的 级邻域也可以表示为 的 级邻域。
于是我们考虑在点集的“中心”,即邻域的 最小时统计,容易发现对于所有不是全集的某个邻域,都存在唯一的一个点 使得邻域的 最小(尽可能不溢出),于是我们单独统计全集,接下来考虑枚举一个点并统计它作为中心的邻域。
令 表示 在树上最远点的距离, 表示次远点的距离,容易换根求出 。
首先 不能取 的值,因为我们现在只统计不是全集的集合。
接下来考虑 是中心的条件:不能存在某个相邻的 使得 的 级领域和 的 级领域相同,可以发现这种情况仅当除了 方向的其它方向的子树内都是满的,显然 只能在 所在子树的方向,且其它方向最远距离的点的距离都 。(在 处 也能统计到)于是我们得到 不能取 的值。
则 可以选择的 在 任意取,对所有值求和后加上全集即可。
接下来并不是所有点都可以选了,但我们仍然考虑在邻域邻域的中心 处统计答案,即使这个中心并不能选择(我们统计的其它某个可以选的 的 级邻域但因为溢出而以 为中心)。
若 可以选择,则它作为中心的情况和上面相同。
若 不能选择,则需要 某个方向的一个可选择的 ,填满它的子树并从 向外延伸向其它方向。
我们把 当作中心的话,需要这个 所在的子树被填满(这样才能使中心向 偏移,否则中心显然不能是 ),并向外蔓延的距离至少要比这个子树的深度大,才可以把 当作中心。
所以考虑 能够取的最小值,即所有存在可以选择的点 的子树中,最深点深度的最小值,称为 ,通过换根求出即可,那么这个点可取的区间即 ,对所有点求和再加上全集即可。
其实最开始解决这个问题时,我采用的办法是树定一个根,然后对于每个点集在可行的最靠上的 的邻域统计。
在解决 为所有点的情况时还可以用类似的办法解决(在钦定邻域中心不能上移的位置统计),但是无法拓展到 不是全集的情况。
这启示我们在统计无根树问题的时候,最好还是采用更加「无根」的统计方式,比如“中心”、“重心”、“最近”之类的,而不是“公共祖先”、“最上方”之类的有根树方向。
本文已经结束了。本文作者:ღꦿ࿐(DeepSea),转载请注明原文链接:https://www.cnblogs.com/Dreamerkk/p/18112488,谢谢你的阅读或转载!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步