QOJ12118 Dendrology 解题报告
QOJ12118 Dendrology 解题报告
题目大意
给定一颗树,对于一个点集 \(S\),定义 \(f(S)\) 表示包含 \(S\) 中所有点的最小联通子图的节点数;\(S_{l,r}=\{i | l\le p_i\le r \}\),\(g(p)=\sum_{1\le l\le r\le n} f(S_{l,r})\)。给定一个排列 \(p\),树上第 \(i\) 个节点的编号为 \(p_i\)。有一些修改操作,每次交换指定边两个端点的编号,求出 \(g(p)\)。
思路分析
考虑刻画 \(f(S)\)。由于是在树上,求最小联通子图相当于求一颗虚树,考虑这可虚树的点的数量如何计算,显然,其等于 \(S\) 中任意两点的最短路径上的所有点之和;如何形式化地刻画呢,由于修改操作和边强相关,于是不妨使用边来刻画这个信息,得到:
将 \(f(S)\) 的表达代入 \(g(p)\),得
记 \(I(A)\) 表示集合 \(A\) 在值域上连续子区间的数量 \(^{[1]}\),由容斥原理可以得到
现在,核心问题就变成如何计算 \(I(A_v),I(\bar{A_v})\)。
注意到,每次交换操作只会影响子节点的子树的集合,而其他部分的集合由于构成元素未发生变化,因此不会改变。于是不妨只去维护 \(\delta(I(A_v)+I(\bar{A_v}))\)。
具体的,利用 set 维护值域上被连续选中的点的编号,在加入/删除点时动态维护 \(I(A_v),I(\bar{A_v})\),然后在如此递归计算得到每一个点的贡献后,使用 DSU On Tree 自底向上合并答案。对于每次修改,直接暴力变更然后记录变化量,最后就可以跑一遍前缀和得到最终答案。
注释
[1] : 由于题目中求的是 \(S_{l,r}\) 这样一个连续编号区间,因此我们要知道一个点为根的子树内包含了多少个连续区间,也就是值域上的连续段。

浙公网安备 33010602011771号