先考虑(O(n^2))的做法。
考虑一个在叶子的农民怎么抓住B。显然农民会向B走。
由于每一个节点B都可能走,如果一些农民向一个点x走,则要满足B到x的距离<农民到x的距离,这样子才能成功逃走。
把B定为根,发现如果一个节点被农民走,则它的子节点就不用被走了。
设(f_i)表示所有叶子节点到i的最短距离。
以公式表示,如果(dep_i>=f_i)且(dep_{fa_i}<f_i)则ans++。
这样子,我们dfs出根到每个节点的距离,再dfs出一个点到子树内最近的叶子结点的距离,这样子就能算出一个B在一个节点的答案。
我们要寻求时间复杂度更加优秀的做法。
对于一个树连通块,设(d_i)表示(i)点的度数。
如果我们在上面的限制条件上不统计(dep_{fa_i}<f_i),由于(dep)在(i)向上走是递减的,(f_i)是递增的,所以被统计的,一定是个连通块。
一个很巧妙的转化:显然(sum d_i =2*(n-1))
(sum d_i+1=2*n-1)
(1=sum {2-d_i})
这样子我们可以构造出(1)。
问题转为求(sum [dep_i>=f_i](2-d_i))
发现(sum (2-d_i)=2*n-2*(n-1)=2)
设点x的答案是(ans_x)
则(ans_x=sum [dis(x,y)>=f_y](2-d_i))
(f)可以两遍dfs求出来。
ans可以点分求。使用树状数组维护分治中心的答案即可。