首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

深度剖析倍增算法求解最近公共祖先(LCA)的细枝末节

1. LCA(最近公共祖先) 倍增算法的基本思想在前面的博文中有较详细的介绍,本文不再复述。此文仅讲解如何使用倍增算法求解多叉树中节点之间的最近公共祖先问题。 什么是最近公共祖先问题?...如上图,LCA(1,2)=1。 如果 u不是v 的祖先,并且 v 不是 u 的祖先,那么 u,v 分别处于 LCA(u,v) 的两棵不同子树中。...如LCA(6,7)=3,因节点6和节点7 互不为祖先,节点6在LCA(6,7)的左子树中,节点7在LCA(6,7)的右子树中。...前序遍历中,LCA(S) 出现在所有S 中元素之前,后序遍历中 LCA(S) 则出现在所有 S 中元素之后。这个很好理解。...如上所述,在向上跳跃时,采取由大到小的方案更能提升查询性能。也就是说,在向上跳跃过程中,尽可能一步迈大点。 向上跳几次? 现在继续探讨另一个问题,一个节点向上跳到其父节点,需要跳几次。

39310

C++ 倍增算法求解最近公共祖先(LCA)

如上所述,在向上跳跃时,采取由大到小的方案更能提升查询性能。也就是说,在向上跳跃过程中,尽可能一步迈大点。 向上跳几次? 现在继续探讨另一个问题,一个节点向上跳到其父节点,需要跳几次。...也就是向上跳2次,那么,这个2次是如何得知的? 答案是根据节点到根节点的深度。...当j>0时,father[i][j]= father[ father[i][j-1]][j-1]。 其实这个道理也简单,在以2 倍增的表达式中满足: 21=20+20。 22=21+21。...总结如下: 当跳到的节点是 2 个节点的共同祖先时,则需要再减少指数,重新跳。 当跳到的节点不相同,可以再重新计算深度,继续向上跳。...知道了节点在树上的深度后,如何计算出处于不同深度的节点应该跳多次(也就是 j 指数的取值范围)? 前文举例说明过,如果深度为 3 ,取 3的对数,因 21<3<22。

42710
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    BZOJ2746: 旅行问题(AC自动机 LCA)

    由于地 区数有可能超过26个,便产生了一个问题,如何辨别名字相同的地区?于是yz规定,一个 地区的描述必须包含它的所有上级,且上级按次序排列。于是,一个地区的描述是一个字符 串。...值得注意的是,每个地区最多有一个上级,同一上级的地区之间名字不同,没有上级的 地区之间名字不同。现在,yz对外公布了n个地区的描述,这些描述中包含了Z国所有地区的描述,并让 你处理来访者的旅行问题。...现有m对人访问这个国家,对于每对人,第一个人喜欢第i个描述中的第j个地区,设 这个地区描述为s1,第二个人喜欢第k个描述中的第l个地区,设这个地区描述为s2。...这题我一开始按fail图做的,然后死活90分,调了一下午,心态爆炸。。 说出来泥萌可能不信,如果我要是在2012年以前出生,这题可能就是我出的了qwq。。...然后我自己证了一个多小时,得到一条性质: 点$x$与点$y$在$fail$树中$lca$处的到的字符串,为模式串中与$x,y$公共后缀最长的前缀 本来想把这题出出来着,结果百度了一下:fail树+lca

    37220

    正则表达式

    看到这里您肯定会觉得眼花缭乱,对正则表达式产生反感,不要怕,老师常说,记是记不住的,所以我们只需要在需要用到的时候能找到就行,我想肯定没有人去花那么多功夫去背这些东西。...序列“\\”匹配“\”而“\(”则匹配“(”。 ^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 $ 匹配输入字符串的结束位置。...+等价于{1,}。 ? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。 {n} n是一个非负整数。匹配确定的n次。....*$ 匹配双字节字符(包括汉字在内) [^\x00-\xff] 汉字(字符) [\u4e00-\u9fa5] Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/ 中文及全角标点符号...这里只列举在如何.NET和JS中使用正则表达式,其他的有兴趣可以问度娘。 在.NET中使用正则表达式:        简单画个窗体: ?

    1.6K20

    使用 pyparsing 的部分求解

    在上下文环境中,我正在研究工业经济模型(生命周期评估或 LCA),其中这些公式表示流程之间的材料或能量交换量。变化量可以是几个参数的函数,例如地理位置。...公式和变量引用的链存储在一个有向无环图中,以便公式总是可以简单地求解。公式作为字符串存储在数据库中。问题:是否可以解析公式,以便解析后的求解结果也可以存储在数据库中(作为要评估的字符串或其他内容)?...有没有类似项目或库的示例可以参考?我不是程序员,只是一个想在业余时间完成自己的论文并制作一个开源 LCA 软件模型的学生。这种方法是否太慢?...然后你只需获取并反序列化表达式,而不是重新解析原始表达式即可。...缓慢的部分是解析,所以你在使用某种中间的可重复求解形式来保存这些结果的道路上是正确的。求解部分应该相当快。第二个缓慢的部分将是从你的数据库中获取这些序列化的结构。

    11810

    SD NAND存储功能描述(17)命令类d

    响 应所有响应都通过命令行CMD发送。响应传输总是从与响应码字对应的位串的最左位开始。代码长度取决于响应类型。响应总是以起始位(总是0)开始,后面是指示传输方向的位(card = 0)。...在下表中以“x”表示的值表示变量项。除了R3类型(见下文)之外的所有响应都受CRC保护。每个命令码字以结束位(总是1)结束。对于SD存储卡有五种类型的响应。SDIO卡支持额外的R4和R5响应类型。...有关SDIOl命令和响应的详细信息,请参阅SDIO卡规范。它们的格式定义如下:R1(正常响应命令):码长为48位。45:40表示要响应的命令的索引,该值被解释为二进制编码数(介于0和63之间)。...卡的状态用32位编码。请注意,如果涉及到卡的数据传输,那么在传输每个数据块后,数据线上可能出现忙音信号。数据块传输后,主机检查是否忙。R1bR1b与R1相同,在数据线上传输一个可选的忙音信号。...卡支持电压信息由CMD8的响应发送。Bits 19-16表示卡支持的电压范围。接受所提供电压的卡返回R7响应。在响应中,卡回显参数中设置的电压范围和校验模式。R7中“电压接受值”格式如下方表格所示。

    9610

    论文赏析用序列标注来进行成分句法分析

    该序列用相邻两个结点的公共祖先(CA)数量和最近公共祖先(LCA)的label来表示一棵树,并且证明了这个树到序列的映射是单射但不是满射的,但是提出了一系列方法来解决这个问题。...没什么好说的,就是一个序列标注模型,下面重点就是介绍如何设计函数 ? 。 编码 之前说到了将一棵有 ? 个叶子结点的句法树转化为长度为 ? 的序列,这个序列是这样生成的:对于单词 ?...还有一种表示成后一个数与前一个数的差值,这样能减少元组的数量,但是会出现负数。当然在这个例子中貌似并不能看出数量减少了。。。 ? 叉树编码:如果句法树所有产生式全部是 ?...的LCA数量与 ? 和 ? 的LCA数量的差值。 最后这就验证了括号序列和之前的编码是一一对应的,单射性得证。解码的时候只需要将数字直接转化成对应的括号序列就行了。...而加上了非终结符之后,单射性不会受到影响。因为虽然两棵相同结构但是拥有不同非终结符的句法树,转化成括号序列后是相同的。但是因为之前的定义中,还有一个变量 ?

    40440

    Python——正则表达式特殊符号及用法

    对于高级的使用,你可能需要更关注匹配引擎是如何执行给定的 RE,并通过一定的方式来编写 RE,以便产生一个可以运行得更快的字节码。...字符类,匹配所包含的任意一个字符注1:连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位则仅作为普通字符注2:特殊字符仅有反斜线 \ 保持特殊含义,用于转义字符。...,只有在字符类中才表示“退格”注2:\u 和 \U 只有在 Unicode 模式下才会被识别注3:八进制转义(\数字)是有限制的,如果第一个数字是 0,或者如果有 3 个八进制数字,那么就被认为是八进制数...=(0, 8), match='abbbbbbc'> >>> #如何匹配0-255中的数字 >>> re.search(r'[1]\d\d|2[0-4]\d|25[0-5]]','188') 0, 3), match='188'>>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1

    1.4K100

    NOIP训练营集训笔记—信息学基础算法(倍增与分治算法)

    一、倍增算法: 定义:用f[i][j]表示从i位置出发的2j个位置的信息综合(状态) 一个小小的问题:为什么是2j而不是3j,5j,…?...2.树上倍增LCA(最近公共祖先): 一般是用线性Tarjan算法来求解(这个Tarjan算法和图论中求有向图强连通分量的Tarjan不同,都是一个人发明的),但是在ZHX十年的信息学奥赛生涯中没有用到这个算法...(j的范围大概[20,30)≈nlogn,只要保证2j>节点数目n即可) 现在我们构造出来这个f数组,下面介绍如何求两个点的LCA: 定义数组depth[i]表示i这个节点的深度,有以下两种情况: ①depth...这个判断是防止一开始跳之前p1=p2这种情况 { p1=f[p1][0];//因为上面的循环p1,p2只是走到了LCA的下方,这个判断只是处理最后一步:把p1或p2往上跳到它的父亲,就是LCA...归并过程: 比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1; 否则,将第二个有序表中的元素b[j]复制到r[k]中,并令j和k

    68450

    grep正则获取特定内容之零宽断言

    这里我们使用了-o和-P选项,指定-o是因为grep默认是显示匹配的那一行,我们只关心精确匹配的部分而不是整行。...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 (?的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。. \num 匹配num,其中num是一个正整数。...:>(.)1>|\s+\/>)$/ 删除代码\注释 (?<!http:|\S)//.*$ Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/

    1.6K20

    正则表达式速查表

    正则表达式在工作中经常用,但是有些东西就是记不住,我从来不强求自己去记记不住的东西。我的选择是整理出来,用的时候查。如下是我常用的正则表达式速查表(不是我的作品)。...`”可以匹配“`does`”或“`does`”中的“`do`”。?等价于{0,1}。 || {n} | n是一个非负整数。匹配确定的n次。...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 || (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 || (?...| Unicode编码中的汉字范围 | /^[\u2E80-\u9FFF]+$/ |## 正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。

    36520

    JavaScript – 正则表达式

    +等价于{1,}。 ? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。 {n} n是一个非负整数。匹配确定的n次。...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 (?的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。. \num 匹配num,其中num是一个正整数。....*$ Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/ 发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/107631.html原文链接:https

    24610

    正则表达式语法速查

    正则表达式的应用范围非常之广泛,最初是由Unix普及开来的,后来在广泛运用于Scala 、PHP、C# 、Java、C++ 、Objective-c、Perl 、Swift、VBScript 、Javascript...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 (?的两个数字长。例如,“\x41"匹配"A"。"\x041"则等价于"\x04&1"。正则表达式中可以使用ASCII编码。. \num 匹配num,其中num是一个正整数。....*$ 匹配双字节字符(包括汉字在内) [^\x00-\xff] 汉字(字符) [\u4e00-\u9fa5] Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/ 中文及全角标点符号

    52310

    使用Python验证常见的50个正则表达式

    [a-zA-Z0-9_-]+)") strs = '我的私人邮箱是zhuwjwh@outlook.com,公司邮箱是123456@qq.org,麻烦登记一下?'...:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) 案例: pattern = re.compile(r"((?...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 (?...脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位(或末尾)则仅作为普通字符。

    1.5K10

    Uber提出损失变化分配方法LCA,揭秘神经网络“黑盒”

    结果 1:训练很嘈杂 Uber 考虑的第一个聚合是 LCA 值在所有参数和所有迭代上的分布。...显示所有 LCA 元素分布情况的直方图(所有迭代中的所有参数),显示只有不到一半是负数(帮助)。相应的直方图以对数刻度(左)显示,以查看分布的尾部和常规刻度(右),以便更清楚地显示负 / 正比率。...LCA 也是重尾分布的:如果它是正态分布的,那么对数空间中的直方图就会呈现出倒抛物线的形状。 Uber 可以通过计算帮助(绿色)而不是受伤(红色)的权重百分比来量化这种张力。...先前的研究已经发现了层表示的广泛手链模式,但通过使用 LCA,Uber 可以在较小的范围内检查层间的学习。 LCA 方法的一个有用的特性是,它让研究人员可以分析他们所关心的任何损失函数。...换句话说,该类的损失由于该层在迭代 t 上的移动而减少,而非由于 t+1 或 t-1 的移动而减少。

    40220

    正则表达式必知必会 - 使用子表达式

    分隔,因此,在正则表达式中要转义为 \.。在这个例子里,模式 \d{1,3}\.(最多匹配3个数字字符和随后的.)连续出现了3次,所以同样可以用重复来表示。下面是同一个例子的另一种写法。...set (0.00 sec)         把选项全都归入一个子表达式里,这样 | 就知道打算匹配的是出现在分组中的选项之一。...每个子表达式都出现在括号中,彼此之间以 | 分隔,意思是只需匹配其中某一个子表达式即可,不用全都匹配。随后的 \. 用来匹配 ....因为模式是从左到右进行评估的,所以当有 4 个表达式都可以匹配时,首先测试第一个,然后测试第二个,以此类推。只要有任何模式匹配,就不再测试选择结构中的其他模式。...理解的关键是要将其分解开,每次只分析一个子表达式,把它搞明白。按照先内后外的原则来进行,而不是从头开始,逐个字符地去阅读。嵌套子表达式其实远没有看上去那么复杂。

    22730

    使用Python验证常见的50个正则表达式

    [a-zA-Z0-9_-]+)") strs = '我的私人邮箱是zhuwjwh@outlook.com,公司邮箱是123456@qq.org,麻烦登记一下?'...:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) 案例: pattern = re.compile(r"((?...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 (?...脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位(或末尾)则仅作为普通字符。

    1.5K20

    使用Python验证常见的50个正则表达式

    [a-zA-Z0-9_-]+)") strs = '我的私人邮箱是zhuwjwh@outlook.com,公司邮箱是123456@qq.org,麻烦登记一下?'...:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) 案例: pattern = re.compile(r"((?...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 (?!...预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 (?...脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位(或末尾)则仅作为普通字符。

    1.4K30
    领券