热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LCA倍增算法常见误区及优化模板分析

本文深入剖析了LCA倍增算法中常见的误区,并通过具体的错误代码示例,详细解释了这些误区的成因及其对算法性能的影响。在此基础上,文章提出了一种优化的模板实现方法,旨在提高算法的效率和稳定性,适用于大规模数据处理场景。

先上我原来的错误的代码

typenode&#61;^link;link&#61;recordnum:int64;next:node;end;varfa:array[0..300000,0..100] of int64;dep:array[0..300000] of int64;nd:array[0..300000] of node;b:array[0..300000] of boolean;dl:array[0..300000] of int64;n,m,maxdep,ans,t1,t2:int64;i:longint;procedure maketree;vart1,t2,head,tail:int64;i,j:longint;p:node;beginfor i:&#61;0 to n dob[i]:&#61;false;for i:&#61;1 to n-1 dobeginread(t1,t2);new(p);p^.num:&#61;t2;p^.next:&#61;nd[t1];nd[t1]:&#61;p;new(p);p^.num:&#61;t1;p^.next:&#61;nd[t2];nd[t2]:&#61;p;end;new(p);head:&#61;1;tail:&#61;1;dl[head]:&#61;1;b[1]:&#61;true;while head<&#61;tail dobeginp:&#61;nd[dl[head]];while p<>nil dobeginif b[p^.num]&#61;false thenbegininc(tail);dl[tail]:&#61;p^.num;fa[p^.num,0]:&#61;dl[head];dep[p^.num]:&#61;dep[dl[head]]&#43;1;b[p^.num]:&#61;true;if dep[p^.num]>maxdep then maxdep:&#61;dep[p^.num];end;p:&#61;p^.next;end;inc(head);end;for j:&#61;1 to trunc(ln(maxdep)/ln(2))&#43;1 dofor i:&#61;0 to n doif dep[i]>&#61;1<thenfa[i,j]:&#61;fa[fa[i,j-1],j-1];end;procedure lca(a,b:longint);vari,t:longint;beginif dep[a]>dep[b] thenbegint:&#61;a;a:&#61;b;b:&#61;t;end;if dep[a]<>dep[b] thenfor i:&#61;trunc(ln(dep[b]-dep[a])/ln(2)) downto 0 doif dep[b]-1<&#61;dep[a] thenbeginb:&#61;fa[b,i];ans:&#61;ans&#43;1<<i;end;if a<>b thenfor i:&#61;trunc(ln(dep[a])/ln(2)) downto 0 doif fa[a,i]<>fa[b,i] thenbegina:&#61;fa[a,i];b:&#61;fa[b,i];ans:&#61;ans&#43;1<<(i&#43;1);end;if a<>b then inc(ans,2);end;beginreadln(n);if n&#61;1 thenbeginwriteln(0);halt; end;maketree;readln(m);read(t1);for i:&#61;2 to m dobeginread(t2);lca(t1,t2);t1:&#61;t2;end;writeln(ans);end.

这个写法WA了一个点&#xff0c;答案比标准答案大。

最后发现可能是ln出现了误差&#xff0c;导致结果偏小&#xff0c;使两点无法移到同层。在后面的移动中无论怎样都无法移到同点&#xff0c;使答案比原来大二

 

改正后的模板

typenode&#61;^link;link&#61;recordnum:int64;next:node;end;varfa:array[0..300000,0..100] of int64;dep:array[0..300000] of int64;nd:array[0..300000] of node;b:array[0..300000] of boolean;dl:array[0..300000] of int64;n,m,maxdep,ans,t1,t2:int64;i:longint;procedure maketree;vart1,t2,head,tail:int64;i,j:longint;p:node;beginfor i:&#61;0 to n dob[i]:&#61;false;for i:&#61;1 to n-1 dobeginread(t1,t2);new(p);p^.num:&#61;t2;p^.next:&#61;nd[t1];nd[t1]:&#61;p;new(p);p^.num:&#61;t1;p^.next:&#61;nd[t2];nd[t2]:&#61;p;end;new(p);head:&#61;1;tail:&#61;1;dl[head]:&#61;1;b[1]:&#61;true;while head<&#61;tail dobeginp:&#61;nd[dl[head]];while p<>nil dobeginif b[p^.num]&#61;false thenbegininc(tail);dl[tail]:&#61;p^.num;fa[p^.num,0]:&#61;dl[head];dep[p^.num]:&#61;dep[dl[head]]&#43;1;b[p^.num]:&#61;true;if dep[p^.num]>maxdep then maxdep:&#61;dep[p^.num];end;p:&#61;p^.next;end;inc(head);end;for j:&#61;1 to trunc(ln(maxdep)/ln(2))&#43;1 dofor i:&#61;0 to n doif dep[i]>&#61;1<thenfa[i,j]:&#61;fa[fa[i,j-1],j-1];end;procedure lca(a,b:longint);vari,t:longint;beginif dep[a]>dep[b] thenbegint:&#61;a;a:&#61;b;b:&#61;t;end;if dep[a]<>dep[b] thenfor i:&#61;trunc(ln(dep[b]-dep[a])/ln(2))&#43;10 downto 0 doif dep[b]-1<&#61;dep[a] thenbeginb:&#61;fa[b,i];ans:&#61;ans&#43;1<<i;end;if a<>b thenfor i:&#61;trunc(ln(dep[a])/ln(2))&#43;10 downto 0 doif fa[a,i]<>fa[b,i] thenbegina:&#61;fa[a,i];b:&#61;fa[b,i];ans:&#61;ans&#43;1<<(i&#43;1);end;if a<>b then inc(ans,2);end;beginreadln(n);if n&#61;1 thenbeginwriteln(0);halt; end;maketree;readln(m);read(t1);for i:&#61;2 to m dobeginread(t2);lca(t1,t2);t1:&#61;t2;end;writeln(ans);end.

 

转:https://www.cnblogs.com/zhujiangning/p/5252868.html



推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • python的交互模式怎么输出名文汉字[python常见问题]
    在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>,此时我们可以使用print() ... [详细]
  • 火星商店问题:线段树分治与持久化Trie树的应用
    本题涉及编号为1至n的火星商店,每个商店有一个永久商品价值v。操作包括每天在指定商店增加一个新商品,以及查询某段时间内某些商店中所有商品(含永久商品)与给定密码值的最大异或结果。通过线段树分治和持久化Trie树来高效解决此问题。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 深入解析:手把手教你构建决策树算法
    本文详细介绍了机器学习中广泛应用的决策树算法,通过天气数据集的实例演示了ID3和CART算法的手动推导过程。文章长度约2000字,建议阅读时间5分钟。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
author-avatar
天王2502871933
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有