求导的思想找极值点挺不错的,还有点分治降低树的高度。
1. 题意
求有点权、边的长度的树的重心,距离定义为 $(\sum w)^{\frac32}$,注意要求落在点上,并且求出该点到其他点的距离和。
$n\leq 2 \times 10 ^ 5$。
2. 题解
首先,暴力 $O(n ^ 2)$ 可以 TLE。
假设距离和函数为 $f(x) = \sum_{i = 1}^n d(i, x)^\frac32$。
我们考虑假设退化成一条链的情况:这个一定是一个下凸函数,我们可以直接三分答案,每一次求 $f(x)$ 为 $O(n)$ 的,总复杂度为 $O(n \log n)$。
可不可以不用三分呢?
观察到这个函数是一个多项式,我们可以对其求导。
最开始,这个导函数一直是负,突然到了最优解 $u$ 附近的时候,边为了正,很明显,我们可以先得到导函数,再对导函数二分查找第一次变为正的位置。
但是我们来到树上的时候,不能一步跳很远,只能单步跳,时间复杂度明显和高度 $h$ 有关,为 $O(nh)$,怎么办呢?
相信你已经想到了,直接点分治重构树!
我们看一下哪棵子树的导函数是小于 0 的,有小于 0 的向那边跳就是了。
同时有前面的理论,我们可以发现,树的重心一定只有一个(可能不在点上而在边上),他向四周扩散都是变大的。
我们层层逼近,一定只有 $\log n$ 层,时间复杂度为 $O(n \log n)$,可以通过。
总结:求导逼近极值点;点分治降低树高度。
1 | void dfs(int x, int fa, double &dev, int nowd) |