『树的直径、重⼼』Day10
Drazil and Morning Exercise
\(f\) 可以换根求。
对于一段乱序序列,你不好求其中 max - min 的限制。
根据重心的性质,如果你让重心为 root,那么向下 \(f\) 一定单减。
这样,你就对每个点在末尾的情况,树上倍增找到最大的点,树上差分即可。
现在想到了好像可以线段树合并,那么你当前点就作为 min,直接在 ds 里面找一个 max 即可。
他们并查集怎么做的没看懂好像。
Weighed Tree Radius
转化:设 \(d=\max \{ dis(x,y)+a_x+a_y \}\),那么 \(r=d/2\)。
证明显然?因为中间路径上边权是 1,你一定可以调整使得 Root 在路径中间,否则肯定是只能选择 \((x,x)\) 作为直径。
或者说,\(d\) 的定义就很有直径的性质,在 \(d\) 上取中点一定会让 max 距离更小。
所以定义一个广义直径即可,然后动态树直径即可,考虑维护直径端点。
树的重心
考虑每个点作为重心的次数。
式子很好推,注意到 \(S\) 的大小并不好维护,一会是 \(siz\) 一会是 \(n-siz\)。
而且你需要保证 \(S\) 是在子树外面的。
首先 \(n-siz\) 是好算的,只可能出现在上链上,进入时更新,回溯时取消即可,现在来看 \(S\)。
不妨先全局给 \(siz\) 加入,每次维护子树进入和出去后的差,就可以知道这个子树的 \(S\) 信息,减去即可。注意全局的 siz 也要更新的。
最后,对 \(x=rt\) 的情况特判。
Logistical Questions
求导来决定向哪里走,点分治保证复杂度。
晚测:NOIP2015 运输计划
一眼二分答案。
把长度满足的路径直接去掉,我们显然需要去掉剩下的所有路径的公共路径,并且取最大的一条。
包含所有路径可以树上差分判断,注意用 dfn 代替递归实现要快好几倍。还有,树剖求 lca。
Good Sequences (added on 8.21)
pudding monster 的加强版。
每次维护的是 \(r\) 的答案,要维护 \(r\) 的历史和,加个标记就可以。