LGP4211_1 [LNTS 2014] LCA 学习笔记
本题一题多解,此处记录其树剖+线段树做法。
Luogu Link
题意简述
给出一棵 \(n\) 个结点的树,以 \(1\) 为根。令 \(dep[1]=1\)。\(m\) 次询问,每次给定 \(l,r,z\),求 \(\sum_{i=l}^r dep[\text{lca}(i,z)]\)。
\(n,m\le 5^10^4\)。
做法解析
题目多次询问编号在不同 \(l,r\) 区间内的一批点。可是这些点在树上不存在任何的位置关系,信息量是 \(O(N)\) 的。这意味着我们大概要做一个类扫描线的过程:从 \(1\) 到 \(n\) 一个一个加入其贡献,把对 \([l,r]\) 的询问差分成 \([1,r]\) 和 \([1,l-1]\),每加入一个点就处理形如 \([1,i]\) 的询问。
我们来想一下加入一个点要怎么把贡献放进桶里——其实这令人惊讶的简单。我们加入 \(i\) 的贡献时,就给它到根链上的每一个点的桶加上 \(1\) ,取贡献的时候就是求 \(z\) 到根的链和。为什么这是对的呢?首先所有的 \(\text{lca}(i,z)\) 肯定都在 \(z\) 到根的链上,所以我们不会算漏。然后我们来观察一下,对于 \(u\) 给 \(z\) 做的贡献,\(z\) 能取到的 \(u\) 做的贡献刚好就是从 \(\text{lca{u,z}}\) 开始到根的这一段,而这段刚好有 \(dep[\text{lca(u,z)}]\) 个结点,也就是 \(dep[\text{lca(u,z)}]\) 的贡献。说大白话就是:一个点的深度还可以看成是这个点到根节点的点数。
代码实现
//To be continue.
反思总结
树上问题给定结点编号的 \([l,r]\),启示类扫描线做法。
一个点的深度还可以看成是这个点到根节点的点数。