历年 NOIP/CSP 汇总

发布时间 2023-09-01 16:57:34作者: Gemini7X

D2T3 树的重心

当年我做这道题时还太嫩了,只能想到暴力。其实如果会了更高的科技这道题只要稍微对暴力优化一下就能 AC(我也不会含泪拼满暴力了)。

废话不说了,暴力的思路就是枚举每一条边然后求两个子树的重心。

直接求重心的复杂度是 \(O(n)\) 的,我们考虑优化到 \(O(\log{n})\)

我们想要求以 \(x\) 为根的子树的重心,首先有个引理:这个重心一定在以 \(x\) 开头的这条重链上(这里就是轻重链剖分中的重链)。

这其实蛮好理解的,如果 \(x\) 不是重心,则只有其重儿子才有可能是重心,同理只有其重儿子的重儿子才有可能是重心,所以重心一定在重链上。

重心一定有且最多有两个,所以我们在重链上找一个最深的点 \(y\) 使得 \(n-sz[y] \le \frac{n}{2}\),这个点有可能成为重心。

重心的另一个性质是如果两点是重心则其一定相连。这样我们只需判断 \(y\)\(father[y]\) 是不是中心即可。

怎么找到 \(y\)?我们发现在重链上倍增就行,类似倍增求 lca。

怎么维护众多数组?换根就行。