题解都说了,当统计 u u u为根节点的时候,答案就是满足以下条件的 i i i的数量: d i ≥ g i d_i≥g_i di≥gi且 d f a i < g f a i d_{fa_i}<g_{fa_i} dfai<gfai,设这个数量为 a n s ans ans。以下严格证明
首先对于满足这个条件的 i i i,其子树的叶子节点显然最多只有一个有农夫(否则就放多了)
我们考虑任意一个叶子节点 p p p,有 d p ≥ g p = 0 d_p≥g_p=0 dp≥gp=0,但是对于 u u u又有 d u = 0 < g u d_u=0<g_u du=0<gu;于是我们猜想,从 p p p到 u u u的路径上,会有一个临界点,从 p p p到这个临界点的点都有 d ≥ g d≥g d≥g,在这个临界点到 u u u都有 d < g d<g d<g
证:从 p p p出发向 u u u走,每一步 d d d都会减少一,而 g g g要么减少一(当前点到离当前点最远的叶子节点要先走到父亲节点再走到叶子节点,注意中途不会经过当前点)要么增加一(离当前点最远的叶子节点在当前点的子树中,并要满足某种限制条件)要么不变(离当前点最远的叶子节点在当前点的子树中,并且不满足某种限制条件,可以想一下这个限制条件是什么)。所以当第一次 d < g d<g d<g后,之后 g g g的减少程度一定不会超过 d d d的减少程度,也就是说恒有 d < g d<g d<g
有了上述性质我们就可以发现,对于任意一个叶子节点,其到根的路径上有且仅有一个点满足最开始给的不等式,所以对于任意一个叶子节点,我们都可以唯一地指定给一个满足最开始不等式的一个点,而满足最开始不等式的点所管辖的叶子节点集合一定不是空集,也就是说满足最开始不等式的点构成了叶子节点集合的一个划分;而且由上述证明过程可知,设 i i i是满足最开始不等式的点,则离其最近的叶子节点一定在其所管辖的集合中,也就是其子树中(否则的话, i i i走到其父亲, d d d和 g g g都会减一,仍有 d ≥ g d≥g d≥g,与最开始的不等式矛盾)
然后我们就可以知道,我们对于每个满足最开始不等式的点,选出离其最近的叶子节点放置农夫,这样就可以在 a n s ans ans个农夫中抓住bessie。而如果答案比 a n s ans ans小,那么由于鸽巢原理,肯定有一个满足最开始不等式的 i i i,其叶子节点一个都没有放农夫,于是Bessie就可以往 i i i走,在其走到 i i i的时候,一定不会有农夫抓住他,然后她任选一个叶子节点就可以逃跑了
接下来考虑统计满足不等式的点的数量
首先先求出 g g g数组,可以用换根DP,也可以用类似多起点Dij的BFS
接下来如果暴力,我们就可以枚举根节点,然后进行暴力统计,时间复杂度 O ( n 2 ) O(n^2) O(n2);关键就在于根节点,想办法消除根的影响,可以知道 g g g与根无关, d d d其实也与根无关, d [ i ] = d i s t [ x ] [ i ] d[i]=dist[x][i] d[i]=dist[x][i],其中 d i s t [ x ] [ i ] dist[x][i] dist[x][i]表示 x x x到 i i i的距离;那么现在就是处理不了 d f a < g f a d_{fa}<g_{fa} dfa<gfa,接下来的技巧可以记住
设 x x x为根节点, a n s x ans_x ansx就是满足不等式的点的个数,设 i i i为满足不等式的点,以 i i i为根的子树,由握手定理 ∑ d e g v = 2 s i z e i − 1 \sum deg_v=2size_i-1 ∑degv=2sizei−1,其中 v v v是 i i i的子孙。式子可以改写成 1 = ∑ 2 − d e g v 1=\sum 2-deg_v 1=∑2−degv
由上面的证明过程,我们可以知道,不同的 i i i不可能有祖孙关系,所以 a n s x = ∑ i = 1 n [ d i s t ( x , i ) ≥ g i ] ( 2 − d e g i ) ans_x=\sum_{i=1}^n[dist(x,i)≥g_i](2-deg_i) ansx=∑i=1n[dist(x,i)≥gi](2−degi)(也就是每个满足不等式的 i i i的贡献为 1 1 1,将 1 1 1替换为 ∑ 2 − d e g v \sum 2-deg_v ∑2−degv即可)
点分治除了处理静态树上路径,还可以处理静态点对关系,具体来说,就是点分治每次在计算以 x x x为根的子树时( x x x是这棵子树的重心),我们考虑一定经过 x x x的点对即可,可以知道,每个点对在整个点分治过程中会且仅会被统计一次
那么对于这道题目,由于点对关系是有序的(i.e. ( x , i ) (x,i) (x,i)以 x x x为根, ( i , x ) (i,x) (i,x)以 i i i为根),所以树上直接统计就不好做了,我们只能指针扫描数组,具体来说,可以先将所有点全部存入树状数组中,然后在计算某一颗子树的时候,先将这棵子树的所有点对树状数组的操作撤销,再进行统计,统计完之后,再将这棵子树的所有点的操作加回来