【题解】P6071 『MdOI R1』Treequery 区间LCA、主席树、树形结构、分类讨论
题外话:对于树上点 \(u\) 和点 \(v\) 位置关系的分类讨论:
-
\(v\) 在 \(u\) 子树内
-
\(v\) 在 \(u\) 子树外
- \(v\) 是 \(u\) 的祖先
- \(v\) 不是 \(u\) 的祖先(等价为 \(v\) 在 \(u\) 的祖先伸出来的某棵子树内)
回归到本题,考虑编号在 \([l,r]\) 内的点与点 \(p\) 的关系。
-
全部在 \(p\) 的子树内 : 答案为 \(dist(p,LCA([l,r]))\) ,其中 \(LCA([l,r])\) 表示编号在 \([l,r]\) 内的点的 \(LCA\) 。
-
全部在 \(p\) 的子树外
-
一部分在 \(p\) 的子树内一部分在 \(p\) 的子树外:答案为 \(0\) 。
考虑对全部在 \(p\) 的子树外的情况继续分类讨论。
我们可以用点集的 LCA 与其他点的关系,很好的描述点集所在子树与其他点的关系。
对于路经 \(p\to x\) ,可以差分成 \(p\to LCA(p,x)\bigcup LCA(p,x)\to x\) 。
因为在 \(p\) 的子树外,所以公共边一定包含 \(p\) 到 \(p\) 的某个祖先之间的路径上的边,考虑是否包含 \(LCA(p,x)\to x\) 这段路经上且与 \(p\to LCA(p,x)\) 路经上的边不交的边。
-
全部在 \(p\) 的子树外
-
包含 \(LCA(p,x)\to x\) 这段路经上的边:相当于编号 \([l,r]\) 内的点在同一棵 \(p\) 某个祖先伸出去的某棵子树内,那么答案即 \(dist(p,LCA([l,r]))\)。
-
不包含 \(LCA(p,x)\to x\) 这段路经上的边:相当于编号 \([l,r]\) 内的点不在同一棵 \(p\) 某个祖先伸出去的某棵子树内,或 \(p\) 的某个祖先编号在 \([l,r]\) 内。
那么考虑不包含 \(LCA(p,x)\to x\) 这段路经上的边应该如何做。
因为一定包含 \(p\) 到 \(p\) 的某个祖先之间的路径上的边且不包含路经 \(LCA(p,x)\to x\) 上的边,因此答案一定为 \(p\) 到 \(p\) 的某个祖先 \(q\) 的距离 \(dist(q,p)\) 。
对于 \(x\in[l,r]\) ,路经 \(p\to x\) 一定包含路经 \(p\to LCA(p,x)\) 间的所有边,我们要考虑的即所有 \(x\in[l,r]\) ,路经 \(p\to LCA(p,x)\) 的交。
令 \(lca'\) 为 \(p\) 与 \([l,r]\) 内的点的深度最深的 \(LCA\) ,答案即 \(dist(p,lca')\) 。
那么接下来要解决的问题即求得 \(p\) 与 \([l,r]\) 内的点的深度最深的 \(LCA\) 。
考虑将 \([l,r]\) 内的所有点与点 \(p\) 按 \(dfn\) 排序,那么深度最深的 \(LCA\) 即 \(p\) 与其前驱后缀的 \(LCA\) 深的较深的一个(直接考虑 \(dfs\) 的顺序即可)。
发现是一个二维数点类状物:令第一维为编号维,第二维为权值( \(dfn\) )维。
那么每次查询的是一个权值维前缀的 \(max\) ,后缀的 \(min\) 。
分别扫前后缀建主席树区间询问即可。