令 v 为 u 的一个儿子,现在求 h_v,则我们新加了 u 除 v 的儿子的子树部分,可以分两种情况考虑。
没有路径经过 u,则 h_v = h_u + g_u - f_v。
有路径经过 u,则枚举经过 u 但不经过 v 的路径 (x,y,w),则 h_u = \max \{-f_v + h_{lca} + g_{lca} + w + \sum_{k \in path(u,v), k \ne lca} g_k-h_k \}。
第二种情况非常不好统计,考虑再分情况,观察一下发现又可分情况。
我们考虑能否把一层线段树去掉,也就是降维,这里考虑把端点在 u 祖先的其它子树中的降去,则需考虑每次 dfs 到 (u,v) 时,我们查询的一个端点一定在 u 的非 v 子树的路径都是合法的。
首先,我们必须把 lca 为 u 的祖先的路径加入线段树,我们如果算完 f_v 后就把 lca 为 v 的贡献加入,那么查询 u 其他子树时就有问题,考虑算完所有 h_v 后把 lca 为 u 的贡献加入,然后统一 dfs(v),这样是正确的,因为 u 更新 v 的任务完成了我们才加入线段树,即使他不在另一个点 k 的祖先上,那么也不会查到它。这样时间复杂度和空间复杂度都是 O(n \log n)。