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可以点分求。使用树状数组维护分治中心的答案即可。

posted @ 2020-10-20 08:05  celerity1  阅读(93)  评论(0编辑  收藏  举报