P16435 [APIO 2026 中国赛区] 集宝
Genius_Star · · 题解
思路:
令
对于一次询问,考虑依次维护当前所有可能的可达点的集合,初始是
显然这样是有问题的,如果中间某个时刻是空集了怎么办?即若走到一个点
容易发现,令
这是因为若干邻域交一定是联通块,这是显然的,而一个联通块都往一个点贪心的蠕动,最后肯定是全部都到这个点邻域边界的某个点处,简单分讨一下即可证明。
还有一个性质,在从
-
设当前收集了第
r' 个宝石在位置p ,现在要收集第r' + 1 个宝石。 -
若选手从来没有动过,即它一直在
S_l, \cdots, S_{r'} 集合中,现在往S_{r' + 1} 动的路肯定是简单路径。 -
否则选手动过,找到它上次动的时刻
t ,那么它所在位置p 一定是恰好在某个点u 的邻域边界上,根据归纳到达p 走的是简单路径且一定不会经过S_u 中的点;接下来反证法一下,如果p 往回向点v 走了,因为邻域交一定非空,那么v 的邻域S_{r' + 1} 一定包括了p (因为p 是在上一个邻域交的边界上),所以p 不会动,与p 往回走矛盾。
所以你可以发现,对于一次询问,它一定是走一条简单路径,然后接下来一直从某个点开始跳跳跳。
那么这题的做法就呼之欲出了,设
对于每个
若现在选手在
于是我们只需要求
现在问题转化为求区间邻域交了,这个咋做?考虑比上面更强的结论,树上邻域交,不仅是一个联通块,还是一个树上邻域,其中心在其中间某个点或者某条边的中点取到。
为了方便处理,可以在边中间插入一个点,这样两个邻域合并后的邻域中心也在点上;发现这个性质后,求区间邻域交,就比较简单了,考虑用线段树维护,只需要支持快速合并两个邻域成新的邻域了(或者无交):
-
设合并
(u, d_1), (v, d_2) 这两个邻域。 -
若
dis(u, v) > d_1 + d_2 ,则无交,是空集。 -
否则找到
u \to v 链上距离u 为d_1 的点u' ,距离v 为d_2 的点v' ,那么合并出的邻域中心在u' \to v' 链的中点处,分讨一下即可,只需要支持求树上k 级祖先。
求最远的
总时间复杂度为