SN省集 Day2 T1
双城通路题解
下面默认祖先关系包含结点自身。
记:
- \(Sub_S(u)\) 表示在 \(S\) 树中以 \(u\) 为根的子树点集;
- \(Sub_T(u)\) 表示在 \(T\) 树中以 \(u\) 为根的子树点集;
- \(u\) 是 \(v\) 在某棵树中的祖先,等价于 \(v\) 在这棵树中属于 \(u\) 的子树。
路线贡献
记两棵树中从根到点的距离分别为 \(d_S(u)\) 和 \(d_T(u)\)。
若一条跨城隧道位于编号 \(p\) 处,长度为 \(r\),那么它能被从 \(S\) 城 \(x\) 到 \(T\) 城 \(y\) 的路线使用,当且仅当:
- \(p\) 是 \(x\) 在 \(S\) 树上的祖先;
- \(p\) 是 \(y\) 在 \(T\) 树上的祖先。
此时这条路线长度为
把所有位于同一个编号 \(p\) 的隧道合并。设这些隧道长度分别为
并记
并定义
若编号 \(p\) 处的隧道能被 \((x,y)\) 使用,那么每一条这样的隧道都会产生一条不同路线,它们的长度之和为
把与 \(i\) 无关的项提出,得到
整理后就是
这就是编号 \(p\) 处所有隧道对 \((x,y)\) 的总贡献。若 \(p\) 不是 \(x\) 在 \(S\) 中的祖先,或不是 \(y\) 在 \(T\) 中的祖先,则这些隧道对 \((x,y)\) 的贡献为 \(0\)。
固定共同结点
考虑一个编号 \(t\)。计算 \(val_t\) 时,可以理解为暂时假定 \(t\) 之下的所有点之间都没有跨城隧道,只统计 \(t\) 及其祖先处的隧道贡献。
设
再令
此时我们只需要考虑
在这种前提下,来自 \(t\) 及其共同祖先这些隧道的贡献中,\(C_t\) 和 \(B_t\) 已经固定,只剩下 \(d_S(x)+d_T(y)\) 需要最大化。由于边权均为正数,显然应分别在 \(S\) 的 \(t\) 子树和 \(T\) 的 \(t\) 子树中取根距最大的点。因此定义
现在考虑如何处理询问。对于询问编号 \(s\),要求 \(x\in Sub_S(s)\) 且 \(y\in Sub_T(s)\)。如果某个编号 \(t\) 要对这个询问产生贡献,那么以 \(t\) 为根继续向下选出的 \(x,y\) 也必须仍然落在 \(s\) 的两个子树中,因此 \(t\) 必须满足
反过来,只要 \(t\in Sub_S(s)\cap Sub_T(s)\),那么 \(Sub_S(t)\subseteq Sub_S(s)\) 且 \(Sub_T(t)\subseteq Sub_T(s)\),由 \(val_t\) 选出的最优 \(x,y\) 一定是询问 \(s\) 的合法选择。因此最终答案就是这个子树交中的最大点权:
于是问题被转化为一个二维矩形最大值问题。令 \(dfns,outs\) 表示 \(S\) 树的 DFS 序区间,\(dfnt,outt\) 表示 \(T\) 树的 DFS 序区间。对每个编号 \(t\) 建一个点:
- 第一维坐标为 \(dfns(t)\);
- 第二维坐标为 \(dfnt(t)\);
- 点权为 \(val_t\)。
也就是二维平面上的点
对每个 \(s\),需要查询矩形
内的最大点权。
计算点权
先分别 DFS 两棵树,得到:
- \(dfn_S,out_S\) 和 \(dfn_T,out_T\);
- 根到点距离 \(d_S,d_T\);
- 子树内最大根距 \(mxS,mxT\)。
然后在 \(S\) 树上 DFS,维护当前 \(S\) 根到当前点路径上的活跃结点。
进入结点 \(u\) 时,若某个点 \(x\) 在 \(T\) 树中位于 \(u\) 的子树内,则 \(u\) 也是 \(x\) 在 \(T\) 树上的祖先。因此把 \(u\) 的贡献加到 \(T\) 树 DFS 序区间:
用两个支持“区间加、单点查”的树状数组,分别维护 \(cnt_u\) 和 \(base_u\)。访问到当前结点 \(u\) 时,在位置 \(dfn_T(u)\) 查询,就能得到 \(C_u\) 和 \(B_u\)。
于是可以算出
DFS 离开 \(u\) 时撤销它的区间贡献即可。
矩形最大值
现在要对每个 \(s\) 求二维矩形内最大点权。
当前实现使用线段树分治处理第一维 \(dfn_S\):
- 对每个询问 \(s\),它在第一维上的区间为 \([dfn_S(s),out_S(s)]\);
- 把这个区间挂到线段树上某个跨过中点的结点,递归处理;
- 在处理线段树结点 \([l,r]\) 时,中点为 \(mid\);
- 从 \(mid\) 向左扫描,把对应点按 \(dfn_T\) 插入一棵维护最大值的线段树;
- 处理左端点等于当前扫描位置的询问;
- 再从 \(mid+1\) 向右扫描,类似处理右端点等于当前扫描位置的询问。
对每个询问 \(s\),第二维只需要在线段树中查询
上的最大值,并更新 \(ans_s\)。
每个点和每个询问在分治线段树中只会参与 \(O(\log n)\) 次,因此这一部分复杂度为
也可以使用二维线段树、归并树等静态二维矩形最大值结构完成。
复杂度
合并隧道和两棵树 DFS 的复杂度为
计算所有 \(val_t\) 的复杂度为
处理所有矩形最大值询问的复杂度为
总时间复杂度为
空间复杂度为
或按实现方式为线性到 \(O(n\log n)\) 级别。
注意答案可能很大,所有距离、贡献和答案都需要使用 long long。

浙公网安备 33010602011771号