ZJOI2019 语言

发布时间 2023-09-25 18:41:31作者: Ender_32k

Day 0001 0101。

考虑对每个点 \(u\) 计算贡献,求出所有经过它的路径的两个端点,包含这些点的最小连通块大小就是以 \(u\) 为端点的 \((u,v)\) 答案数对的个数。

根据经典结论,对于 \(m\) 个点的点集 \(u_1,u_2,\cdots ,u_m\),钦定 \(u_0=u_m\) 且根据 DFS 序排序,则以任意点为根,包含它的最小连通块大小为 \(\sum\limits_{i=1}^md_{u_i}-d_{\text{lca}(u_i,u_{i-1})}\)\(d_u\)\(u\) 的深度。

发现如果知道所有经过 \(u\) 的路径的端点,再插入一条经过 \(u\) 的路径,\(u\) 的贡献也是容易通过在 DFS 序上建立线段树动态维护的。于是相当于 \(m\) 次链修改,每次修改在 \(u,v\) 之间的路径上的线段树插入点 \(u\)\(v\)

树上差分一下,变成单点修改。然后父亲节点的线段树需要从子节点继承而来,线段树合并即可。

使用 DFS 序求 LCA,复杂度 \(O(n\log n)\)