P3233 [HNOI2014] 世界树的题解
P3233 [HNOI2014] 世界树的题解
不是,虚树的题目为什么要用虚树做
【题目大意】
给定一颗无根树,共有 \(n\) 个节点,给定一些询问,每次询问定义 \(m\) 个“管辖点”,树上的节点 \(v\) 被 \(u\) 管辖当且仅当:\(u\) 是“管辖点”;\(u\) 是所有“管辖点”中距离 \(v\) 最近的点;若有多个距离相同的点,\(u\) 是编号最小的。举个例子:在下图中,如果只有 \(4\) 和 \(6\) 是“管辖点”,那么 \(2\) 应该被 \(4\) 管辖。

【具体思路】
众所不周知,这是一道很板的虚树题,如果你学过虚树,你会很套路地想到用虚树来解决这题,在这里提供一种不用虚树的做法。
我们观察一下题目的性质:
- 每一个“管辖点”管辖的范围是一个包含点 \(m\) 的连通块
我们不妨另 \(1\) 为根,那么“管辖点” \(i\) 所管辖的范围就是以 \(i\) 的某一代父亲为根的子树减去一堆小子树。举个例子:在样例 2 7 3 6 9 中,\(3\) 所管辖的范围就是以 \(3\) 为根的子树减去以 \(7\) 为根的子树减去以 \(9\) 为根的子树,\(2\) 所管辖的范围就是以 \(1\) 为根的子树减去以 \(3\) 为根的子树减去以 \(6\) 为根的子树。因此,一个较为清晰的思路就出来了,我们按照每个点的深度为“管辖点”排序,然后依次插入每一个“管辖点”,新插入的“管辖点”只会和一个已插入的“管辖点”的管辖范围产生冲突,按照题目意思处理就行了。
【具体步骤】
还是以样例 2 7 3 6 9 为例,排序后的“管辖点”为 2 6 3 7 9,依次插入。
- 插入“管辖点” \(2\):\(2\) 的管辖范围就是以 \(1\) 为根的子树。
- 插入“管辖点” \(6\):\(6\) 处于 \(2\) 的管辖范围中,故处理与 \(2\) 的冲突。二者的中点 \(1\) 应该属于 \(2\) 管辖,故 \(6\) 的管辖范围为以 \(6\) 为根的子树。
- 插入“管辖点” \(3\):\(3\) 处于 \(2\) 的管辖范围中,故处理与 \(2\) 的冲突。二者的中点 \(3\) 应该属于 \(3\) 管辖,故 \(3\) 的管辖范围为以 \(3\) 为根的子树。
- 插入“管辖点” \(7\):\(7\) 处于 \(3\) 的管辖范围中,故处理与 \(3\) 的冲突。二者的中点 \(7\) 应该属于 \(7\) 管辖,故 \(7\) 的管辖范围为以 \(7\) 为根的子树。
- 插入“管辖点” \(9\):\(9\) 处于 \(3\) 的管辖范围中,故处理与 \(3\) 的冲突。二者的中点 \(4\) 应该属于 \(3\) 管辖,故 \(9\) 的管辖范围为以 \(9\) 为根的子树。
【温馨提示】
朴素做是 \(O(n^2)\),可以用区间修改、单点查询的线段树来维护每个点属于哪一个点的管辖范围,用倍增来做到寻找 \(\text{lca}\)、寻找中点,以达到 \(O(n \log n)\) 的时间复杂度。

浙公网安备 33010602011771号