题意:给定一棵有根树T,给出若干个查询lca(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找一个节点,同时是u和v的祖先,并且深度尽可能大(尽可能远离树根)。通常有以下几种算法:在线算法,每次读入一个查询,处理这个查询,给出答案。离线算法,一次性读入所有查询,统一进行处理,给出所有答案。在线:倍增(基于二分搜索):基本思想就是让u和v同时走到同一高度,然后再一起一步
转载 2023-06-18 20:33:15
56阅读
洛谷P3379 【模板】最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。 输入输出格式 输入格式: 第一行包含三个正整数$N$、$M$、$S$,分别表示树的结点个数、询问的个数和树根结点的序号。 接下来$N 1$行每行包含两个正整数$x$、$y$,表示
转载 2018-06-06 15:30:00
93阅读
2评论
基本概念 最近公共祖先:在一棵有根树中,一对结点$(x, y)$的最近公共祖先(\(LCA\),\(Lowest \ Common \ Ancestor\))定义为它们深度最大的$x, y$共同的祖先结点,即距离$x$和$y$最近的公共祖先结点。 算法思路 原始算法 显然,我们可以从结点$x$开始向 ...
转载 2021-07-24 23:21:00
100阅读
最近公共祖先(\(\rm Least\,Common\,Ancestors\)),简记为 \(\rm LCA\)。顾名思义就是一棵树中的某两个节点的公共祖先中离他们最近,即深度最大的那个。 举个例子: 上图中 \(8\) 和 \(6\) 的 LCA 就是 \(1\)。 那么怎么求 LCA 呢? 1 ...
转载 2021-08-07 18:03:00
114阅读
2评论
考虑一个问题:任意两个点的$LCA$要么是他们的某个祖先,要么是其中某个点。 那么可以分类讨论。 其实可以发现,当某个点被改为黑色后,他的所有祖先对除了他所在的子树的节点的贡献只需计算一遍,就是说,如果之前某个祖先已经对另外的子树的节点取过$max$了,意思就是说他已经作为可能的$LCA$对他们贡献 ...
转载 2021-08-03 21:07:00
116阅读
2评论
[模板]https://www.luogu.com.cn/problem/P3379 const int N = 5e5 + 50,M = 1e6 +50; int h[N],e[M],ne[M],idx; void add(int a,int b) { e[idx]=b,ne[idx]=h[a], ...
转载 2021-09-06 20:29:00
28阅读
2评论
1062 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 1062 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在其中,但这是为什么呢? “为什么呢?”小H
转载 2018-07-26 16:30:00
115阅读
2评论
摘要:本文主要介绍了解决LCA(最近公共祖先问题)的两种算法,分别是离线Tarjan算法和在线算法,着重展示了在具体题目中的应用细节。  最近公共祖先是指对于一棵有根树T的两个结点u和v,它们的LCA(T,u,v)表示一个结点x,满足x是u和v的公共祖先且x深度尽可能的大(也即最近)。  求最近公共祖先有两种方法:一种是离线求解算法,也就是将询问全部存起来,处理完之后一次回答所有询问;另一种方法就
囧啊囧。lca的求法太多了倍增,tarjan,st,lct,hld....后边三个我就不写了,其中st我没写过,估计用不上,在线用倍增,离线用tarjan就行了。嗯。第一种,倍增(O(nlogn)~O(logn),在线):倍增的思想用在树上,即可以求出lca。我们维护二维数组,f[i][j],表示i...
转载 2021-08-11 14:18:25
102阅读
传送门 考场上坚持认为树剖可做,于是几乎爆零 别一直坚持一个思路!就算这个思路很可能是对的但自己不会写也要及时换思路! 但正解思路跟考场上想的思路真的很像,连开的数组都一样 考虑一个点被染黑时可能更新哪些白点的答案 开一个bool two[]和一个int son[],两个标记不共存,上翻修改 然后我 ...
转载 2021-08-03 21:45:00
80阅读
今天终于把倍增的LCA搞懂了!尽管周测都没写,尽管lca其实很简单,但这也是进度君的往前一点点的快乐。学渣的呻吟。 倍增的lca其实关键就在于二进制的二进制的拆分(显然是两次的拆分,很奇妙,懂二进制的自然不觉得什么)。把最关键的地方在这里列举一下吧: 1.f[fa][i]=f[f[fa][i-1]]
转载 2018-09-21 21:32:00
73阅读
2评论
最近公共祖先:在一个有根树中,结点u、v的最近公共祖先是满足是u,v的公共祖先并且深度尽可能大的结点。 1、倍增法 首先如果两个点的深度如果不同,将深度较大的点跳到与深度较小的点一样的深度,再同时向上跳,首次相遇时即为最近公共祖先。 2、树剖法size x为以x为结点的子树的结点的个数 每个结点和它
转载 2017-05-01 21:11:00
101阅读
2评论
最近公共祖先(LCA) 首先是最近公共祖先的概念 (什么是最近公共祖先? ): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共祖先节点。 换句话说,就是两个点在这棵树上距离最近的公共祖先节点 朴素算法 求最近公共祖先的方法有很多,想最简 ...
转载 2021-08-20 15:09:00
230阅读
2评论
方法1:向上标记法 时间复杂度:\(O(n)\) 待查询点为a和b,首先从a点向根节点进行搜索,将路径上的点进行标记, 再从b点向根节点进行搜索,同时检测路径上的点是否被标记过,第一次检测到的点即为a,b两点的最近公共祖先 方法2:倍增 时间复杂度 预处理:\(O(nlog_n)\) 查询: \(O ...
转载 2021-09-04 14:42:00
195阅读
2评论
(原标题:最近公共祖先学习笔记) 其实是假的。 这个,老早就学过了,但是显然由于当时理解得不透彻,很快就遗忘了。 今天,做了一份模拟试题,第一题就是LCA,汗!没办法,只好温习,终于理解透彻了。 最近公共祖先,顾名思义,就是指求树上两个点的第一个公共祖先,或者说是深度最大的公共祖先。 求这个有什么用呢? 一个常见的用途就是求两点简单路径。 有人可能说,这不简单吗?我们把两个点调整到同一个高度,然后
原创 2022-11-18 11:00:43
99阅读
最近公共祖先问题: 情况1:二叉树是个二叉查找树,且root和两个节点的值(a, b)已知。如果该二叉树是二叉查找树,那么求解LCA十分简单。基本思想为:从树根开始,该节点的值为t,如果t大于t1和t2,说明t1和t2都位于t的左侧,所以它们的共同祖先必定在t的左子树中,从t.left开始搜索;如果t小于t1和t2,说明t1和t2都位于t的右侧,那么
原创 2023-04-25 09:54:01
24阅读
向上标记法 时间复杂度:$O(n)$ 待查询点为a和b,首先从a点向根节点进行搜索,将路径上的点进行标记, 再从b点向根节点进行搜索,同时检测路径上的点是否被标记过,第一次检测到的点即为a,b两点的最近公共祖先 倍增 时间复杂度 预处理:$O(nlog_n)$ 查询: $O(log_n)$ 相关概念及性质 节点祖先:从根到该节点所经分支上的所有节点,从根节点到此节点的路径中除了此节点本身(但是
原创 2023-07-15 23:27:43
69阅读
1.倍增LCA 通过记录f[i][j],每个点第2的j次方个父亲的编号,来找LCA 代码中,先要处理出每个点的深度,和father(f[i][0]),然后倍增求出所有的祖先。 work的时候,利用二进制拆分的思想,先把两个节点向上翻到同一个深度,再同时向上翻,直到到了lca的儿子位置,再返回f[x]
转载 2018-05-13 12:02:00
86阅读
2评论
中等 近期公共祖先 查看执行结果 34% 通过 给定一棵二叉树,找到两个节点的近期公共父节点(LCA)。 近期公共祖先是两个节点的公共祖先节点且具有最大
转载 2017-05-22 15:36:00
22阅读
2评论
#include <cstring> #include <algorithm> #include <cmath> using namespace std;const int N = 10010; const int INF = 0x3f3f3f3f; struct edg
原创 2017-08-27 12:30:20
55阅读
  • 1
  • 2
  • 3
  • 4
  • 5