Cow at Large P
先考虑\(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可以点分求。使用树状数组维护分治中心的答案即可。