专栏文章

题解:P11624 [迷宫寻路 Round 3] 挂掉的模板

P11624题解参与者 3已保存评论 2

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
2 条
当前快照
1 份
快照标识符
@miqds8qy
此快照首次捕获于
2025/12/04 03:09
3 个月前
此快照最后确认于
2025/12/04 03:09
3 个月前
查看原文

[迷宫寻路 Round 3] 挂掉的模板

题目描述

有一颗 nn 个节点的有根树。
定义 FakeLCA 函数代码如下:
CPP
int FakeLCA(int u, int v) {
	while (u != v) u = fa[u], v = fa[v];
	return u;
}
其中 fa[i] 表示节点 ii 的父节点,特别的,根的父节点是根本身。
现在给定节点数 nn 和每个节点的父节点,问有多少个有序数对 (u,v)(u,v),满足 1u,vn1\le u,v\le nFakeLCA(u, v) 的结果是 uuvv 的真正的最近公共祖先。

Solution

简单题。
题目给出的代码就是两个节点同时往上跳,问相遇那个点是真正 LCA 的有多少个有序整数对。值得注意的一点是,根的父亲是根本身,并且有序整数对中 u,vu,v 可以相等。
分情况讨论即可。
首先,我们找到这棵树的根 rt,那么 rt 与其他 n1n-1 个点可以互相构成 2n22n-2 个有序对。因为任何节点往上跳,肯定会到达根,而根只会原地不动。
然后是位于 rt 不同子树上的点 u,vu,v。它们正常的 LCA 是 rt,我们记录 szusz_u 表示 uu 子树的大小,那么这样的有序整数对一共有 uson(rt)vson(rt),vuszu×szv\sum_{u∈son(rt)}\sum_{v∈son(rt),v≠u}sz_u\times sz_v 但是如果给出的图是菊花图,那么我们的时间复杂度会退化为 O(n2)\mathcal O(n^2),考虑优化。对于上面那个式子,我们可以化简 uson(rt)vson(rt),vuszu×szv\sum_{u∈son(rt)}\sum_{v∈son(rt),v≠u}sz_u\times sz_v =uson(rt)szuvson(rt),vu)szv=\sum_{u∈son(rt)}sz_u\sum_{v∈son(rt),v≠u)}sz_v =uson(rt)szu×(nszu1)=\sum_{u∈son(rt)}sz_u\times (n-sz_u-1) 这样我们就做到了 O(n)\mathcal O(n) 的时间复杂度。
接着,我们还需要考虑同一颗子树内的节点。由于节点是同时往上跳,所以 LCA 不是 rt 的节点 u,vu,v 必须保证深度相同。所以我们需要对于 rt 的每一颗子树找出深度相等的节点 u,vu,v,它们可以构成一组,统计答案即可。
最后,由于有序整数对中 u,vu,v 可相等,所以我们的答案还需要加上 nn
Ac Code

评论

2 条评论,欢迎与作者交流。

正在加载评论...