【题解】「CTSC2018」 暴力写挂 [*hard]

时间:2021-02-17 14:59:55   收藏:0   阅读:0

考虑边分治。

边分治的时候考虑跨过中心边的点对 \((x,y)\) 的答案。考虑到 \(d_x+d_y-d_{lca(x,y)}\) 其实是 \(\frac{1}{2}(dix(x,y)+d_x+d_y)\) ,这下就跟 \(lca\) 没关系了。 显然在边分治的过程中 \(dis(x,y)\) 也可以被拆开,令 \(p_x\) 表示 \(x\) 到边分治中所属子树的根的距离,显然 \(dix(x,y)=p_x+p_y+1\)

这样的话一个点 \(x\) 的权值就是 \(d_x+p_x\) 。接下来后面那个 \(d‘_{lca‘(x,y)}\) 怎么办?

考虑对当前边分治范围内所有点,在第二棵树上建立虚树。建立虚树后考虑每个点作为 \(lca‘(x,y)\) 的答案即可。这点可以简单树形 DP 解决。

注意到一共分治 \(\log\) 层,每层的所有分治块节点数之和不超过 \(n\) ,虚树点数是 \(O(k)\) 的(\(k\) 为关键点数),因此时间复杂度是 \(O(n\log n)\) 的。

然后就做完了,注意到边分治的点数上界是 \(4n\) ,这下子点数就变成了 \(10^6\) 级别,需要注意实现。注意到建虚树的时候需要求 \(lca\) 并且需要将所有关键点按照 \(dfn\) 序排序,\(O(1)\)\(lca\) 很容易实现,排序的话归并边分治的两个儿子即可。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!