我当时知道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. CSS - 定位属性position使用详解(static、relative、fixed、absolute)

    position 属性介绍 (1)position 属性自 CSS2 起就有了,该属性规定元素的定位类型.所有主流浏览器都支持 position 属性. (2)position 的可选值有四个:sta ...

  2. Java/C++实现装饰模式---模拟手机功能的升级过程

    用装饰模式模拟手机功能的升级过程:简单的手机(SimplePhone)在接收来电时,会发出声音提醒主人:而JarPhone除了声音还能振动:更高级的手机(ComplexPhone)除了声音.振动外,还 ...

  3. Python读文件并写入数组

    直接上代码: # 读文件 def get_venue(file): fname = file # 文件名 # 获取数据长度 len = 0 with open(fname, 'r+', encodin ...

  4. 一个抽取百度定位的教程(下载百度地图Demo+配置+抽取)

    效果展示 已经下载Demo的可以直接到第五步,已经配置好的并可以运行的可以直接到第七步. 1.在浏览器搜索 " 百度定位API ",点击下面这个链接 2.翻到最下面找到并点击 &q ...

  5. 初始化properties

    package com.letech.common; import java.io.IOException; import java.util.Properties; public class Con ...

  6. node安装和环境配置

    参考链接: https://www.cnblogs.com/zwjphp/p/14123746.html 一.安装环境 1.本机:Windows 10 (64位) 2.Node.js:v12.13.0 ...

  7. C语言 之 多线程编程

    一.基础知识 计算机的核心是CPU,承担了所有的计算任务. 操作系统是计算机的管理者,负责任务的调度.资源的分配和管理,统领整个计算机硬件. 应用程序则是具有某种功能的程序,程序是运行于操作系统之上的 ...

  8. 【C++】二叉树的遍历(前中后)- 迭代法

    力扣题目:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ 今天自己琢磨了很久如何不用递归将二叉树的遍历写出来,于是乎写出 ...

  9. 如何让HTTPS站点评级达到A+? 还得看这篇HTTPS安全优化配置最佳实践指南

    0x00 前言简述 SSL/TLS 简单说明 描述: 当下越来越多的网站管理员为企业站点或自己的站点进行了SSL/TLS配置, SSL/TLS 是一种简单易懂的技术,它很容易部署及运行,但要对其进行安 ...

  10. SwitchHosts管理编辑hosts工具

    管理Hosts工具 SwitchHosts 地址: SwitchHosts 开发工程中,针对不同项目设置不同的域名. 办法很多,例如直接编辑hosts文件,通过环境工具提供的功能设置等. 现在要安利一 ...