我当时知道ST表可以 \(O(1)\) 求 LCA 的时候是极为震惊的,可以在需要反复使用 LCA 的时候卡常使用。

ST表!用于解决 RMQ问题

ST表

我可能写得不好,看专业的

怎么实现?

考虑把求 LCA 转换为 RMQ问题。我们对于树求一遍欧拉序,就是那个回溯也会记录的那个。我们处理出每个数第一次在欧拉序中出现的位置,欧拉序上每个位置的深度,以及欧拉序上每个位置出现的点的编号。这些信息都可以在一次 \(dfs\) 中求出。然后不难发现在回溯过程中加入的点是之前遍历的点的祖先,由此也不难推出结论。

在两个点在欧拉序上第一次出现的位置的区间中间的深度最小的点就是这两个点的 LCA

那么直接变成 RMQ问题,上 ST表。

Code:

void dfs(int u,int f,int deep){
dfn[u]=++idx;
app[idx]=u;
dep[idx]=deep;
for(int i=head[u];~i;i=nxt[i]){
if(to[i]==f) continue;
dfs(to[i],u,deep+1);
app[++idx]=u;
dep[idx]=deep;
}
}
inline void init_ST(){
for(int i=1;i<=(n<<1);++i){
st[i][0]=i;
}
lg2[1]=0;lg2[2]=1;
for(int i=3;i<=(n<<1);++i){
lg2[i]=lg2[i>>1]+1;
}
for(int j=1;(1<<j)<=(n<<1);++j){
for(int i=1;i+(1<<j)-1<=(n<<1);++i){
int a=st[i][j-1],b=st[i+(1<<(j-1))][j-1];
if(dep[a]<dep[b]) st[i][j]=a;
else st[i][j]=b;
}
}
}
inline int LCA(int a,int b){
int l=dfn[a],r=dfn[b];
if(l>r) Swap(l,r);
int k=lg2[r-l+1];
int x=st[l][k],y=st[r-(1<<k)+1][k];
return dep[x]<dep[y]?app[x]:app[y];
}

st表 LCA的更多相关文章

  1. 51Nod1766 树上的最远点对 ST表 LCA 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1766.html 题目传送门 - 51Nod1766 题意 n个点被n-1条边连接成了一颗树,给出a~ ...

  2. LCA 算法(一)ST表

    介绍一种解决最近公共祖先的在线算法,st表,它是建立在线性中的rmq问题之上.   代码:   //LCA: DFS+ST(RMQ) #include<cstdio> #include&l ...

  3. 51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径

    51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径 题面 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即 ...

  4. [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)

    [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...

  5. HDU 2586(LCA欧拉序和st表)

    什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细 因为欧拉序中的两点之间,就是两点遍历的过程,所以只 ...

  6. lca最近公共祖先(st表/倍增)

    大体思路 1.求出每个元素在树中的深度 2.用st表预处理的方法处理出f[i][j],f[i][j]表示元素i上方第2^j行对应的祖先是谁 3.将较深的点向上挪,直到两结点的深度相同 4.深度相同后, ...

  7. 【BZOJ-4569】萌萌哒 ST表 + 并查集

    4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 459  Solved: 209[Submit][Status] ...

  8. 【模板】ST表

    给定一个长度为 \(N\) 的数列,和 \(M\) 次询问,求出每一次询问的区间\([l,r]\)内数字的最大值. 说明 对于30%的数据,满足: \(1 \leq N, M \leq 10 , 1≤ ...

  9. hdu6107 倍增法st表

    发现lca的倍增解法和st表差不多..原理都是一样的 /* 整篇文章分成两部分,中间没有图片的部分,中间有图片的部分 分别用ST表求f1,f2表示以第i个单词开始,连续1<<j行能写多少单 ...

随机推荐

  1. canvas 1px 出现模糊解决方法及原理

    关于canvas绘制1像素出现模糊的原因及解决方法 canvas是html5中非常强大的功能,但是在绘制的时候如果出现1像素,例如画一条1像素的线可能出现模糊情况. 一.解决方法 网上比较常见的解决方 ...

  2. canvas系列教程07-canvas动画基础1

    上面我们玩了一个图表,大家学好结构,然后在那个基础上去扩展各种图表,慢慢就可以形成自己的图表库了.也可以多看看一些国外的图表库简单的版本,分析分析,读代码对提高用处很大.我说了canvas两大主流用途 ...

  3. typescript使用入门及react+ts实战

    ts介绍 TypeScript是一种由微软开发的自由和开源的编程语言.它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程. 与js关系 ts与js区 ...

  4. 7.Docker容器使用辅助工具汇总

    原文地址: 点击直达 more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack- ...

  5. flink调优之RocksDB设置

    一.开启监控 RocksDB是基于LSM Tree实现的,写数据都是先缓存到内存中,所以RocksDB的写请求效率比较高.RocksDB使用内存结合磁盘的方式来存储数据,每次获取数据时,先从内存中bl ...

  6. Codeforces Round #700 (Div. 2) --- B(思维)

    传送门 有必要提醒自己一下, 先把题读利索了(手动捂脸) 题目 B. The Great Hero   The great hero guards the country where Homer li ...

  7. Junit单元测试:

    * 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. * Junit使用:白盒测试 * 步骤: 1. 定义一个测 ...

  8. 阿里巴巴稀疏模型训练引擎-DeepRec

    导读:DeepRec从2016年起深耕至今,支持了淘宝搜索.推荐.广告等核心业务,沉淀了大量优化的算子.图优化.Runtime优化.编译优化以及高性能分布式训练框架,在稀疏模型的训练方面有着优异性能的 ...

  9. kafka从入门到了解

    kafka从入门到了解 一.什么是kafka Apache Kafka是Apache软件基金会的开源的流处理平台,该平台提供了消息的订阅与发布的消息队列,一般用作系统间解耦.异步通信.削峰填谷等作用. ...

  10. GO语言学习——切片一

    切片(slice) 数组的长度的固定的.是声明之后不能变的.是类型的一部分 切片是一个引用类型 切片的定义 声明切片类型的基本语法如下: var name []T 其中, name:表示变量名 T:表 ...