这题能黑了是因为洛谷仅有的题解都是些滥用数据结构的解法么……(
考虑一棵广义线段树的形态,和定位区间所得的结点的性质。
对于定位区间 [l,r] 的过程,可以考虑 [l−1,l−1] 和 [r+1,r+1] 对应的结点和它们的 LCA(分别设为 L,R,U)。
注意到定位出来的区间都是 L 到 U 左儿子链上所有结点的在链以外的右儿子和 R 到 U 右儿子链上所有结点的在链以外的左儿子。
那么问题便是算 u 与这些结点的距离和。
不难想到转化为深度和减去 2 倍的 LCA 的深度和。
显然地,可以离线下来,暴力地使用数据结构 O((n+m)log2n) 或 O((n+m)logn) 维护(
实际上没必要,因为这些结点具有比较优美的性质,所以可以通过分类讨论解决。
若 u 不在 U 的子树内或恰为 U,则显然这些结点与 u 的 LCA 即为 u 与 U 的 LCA。
若 u 在 U 的左子树内,设 u 与 L 的 LCA 为 x,则 U 右子树内与 u 的 LCA 均为 U;左子树中 x 以下的结点与 u 的 LCA 显然为 x,而 x 至 U 的左儿子段都是 u 的祖先。
注意特判 u 在 x 的右子树内的情况,此时 LCA 应为 x 的右儿子。
若 u 在 U 的右子树内,与前一情况类似。
线性预处理出每个结点到根链上在链以外的左 / 右儿子个数和深度和即可。
代码:
1 |
|