首页 > 树上倍增求lca

树上倍增求lca

嗯~ o(* ̄▽ ̄*)o

lca是树上两点的最近公共祖先。如果在同一个分支上就是更靠近根的那个点,否则就是大家一起向上走,第一次能都经过的那个点。

根据这两个性质,我们对于每次询问可以把一个向上走到根节点,标记走过的点。然后从另一个点向上走,直到遇到第一个标记过的点即为lca。

如果整个树是一个长链,这样的方法就会退化成一复杂度为n的算法。我们想一想如何优化成为log的策略。

假设两个节点到达lca的距离是m,那么这个m一定是可以被分解成一个二进制数的(废话)。我们可以好好利用一下这个性质。

设数组fa[i][k]表示节点i向上走2^k的父节点,d[i]表示i节点的深度。那么可以得到fa[i][0]是从i向上走1个到达的节点,即父节点。而且还可以得到fa[i][k]=fa[fa[i][k-1]][k-1],因为二进制的定义。d[i]=d[fa[i][0]]+1应该不用再说了吧。

同时还可以维护许多数组表示其他性质,在topsort的时候需要自己加上。

//传入的参数即为你选中的根节点,实际上这个根节点选什么都一样
t=(int)log(n*1.0)/log(2.0)+1;//为最大的k
void bfs(int now)
{stack<int>q;q.push(now);d[now]=1;while(q.size()){int x=q.top();q.pop();for(int j=link[x];j!=0;j=o[j].next){int y=o[j].y;if(d[y])continue;q.push(y);d[y]=d[x]+1;fa[y][0]=x;for(int k=1;k<=t;k++)fa[y][k]=fa[fa[y][k-1]][k-1];//类似于动态规划的转移呦}}
}

然后对于每个询问,先把x向上调整到于y同一深度,如果在同一个链上这个时候应该已经遇到了吧。如果没有遇到就可以俩人一起向上走,知道fa[x][k]==fa[y][k]的时候停下来。

int lca(int x,int y)
{if(d[x]>d[y])swap(x,y);for(int k=t;k>=0;k--)if(d[fa[y][k]]>=d[x])y=fa[y][k];if(x==y)return x;for(int k=t;k>=0;k--)if(fa[x][k]!=fa[y][k])x=fa[x][k],y=fa[y][k];return fa[x][0];
}

 

转载于:https://www.cnblogs.com/qywyt/p/9629211.html

更多相关:

  • 折腾了好久。不过收获还是很多的。第一次自己去画SAM所建出来fail树。深入体会了这棵树的神奇性质。 当然,我最终靠着自己A掉了。(这是我第一次推SAM的性质(以前都是抄别人的,感觉自己好可耻),不过感觉好像是摸着黑行走啊!) 这道题,可以先对第一个串建出后缀自动机。然后第二个串在后缀自动机上跑。 首先,SAM所建出的fail树的性质...

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 当一个IT组织开始走到需要实施网络边缘的旅程时,他们很快意识到面对的挑战与他们在传统数据中心内所经历的挑战不同。 第一个挑战是空间。与更大的核心或区域数据中心同类产品相比,许多边缘站点的物理尺寸更小,因此,需要仔细计划好,尝试在未为其专门设计的空间中安装硬件。  第二个挑战是运行环境。还必须解决的可能面对的冷热温度变化 ,天气,无...

  • 单向循环链表单链表的一个变形是单向循环链表, 链表的最后一个节点的next域不再为None, 而是指向链表的头节点.单向循环链表如图所示:单向循环链表同样单向循环链表也是要使用python来对它的基本功能进行一个封装. 总体大致的功能如下:is_empty() 判断链表是否为空length() 返回链表的长度travel() 遍历ad...

  • 题目: 二叉搜索树与双向链表 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 为了让您更好地理解问题,以下面的二叉搜索树为例: 我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一...

  • 题目:删除链表的节点 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。 返回删除后的链表的头节点。 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为...

  • 【从零开始的ROS四轴机械臂控制】(一)- 实际模型制作、Solidworks文件转urdf与rviz仿真 一、模型制作 1.实际模型制作 2.Solidworks模型制作 二、Solidworks文件转urdf 1.sw_urdf_exporter插件 2.添加坐标系和转轴 3.导出urdf文件 三、rivz仿真...