欧拉序求LCA
使用欧拉序 st 表 O(1) 求 LCA
欧拉序 st 表求 LCA
一开始是从某篇题解里看到的,后来百度了一下就会了(
这是一种预处理 O(nlogn) ,查询 O(1) 的优秀算法。
什么是欧拉序
举个例子,下面是一棵树:

上面有 dfs 与回溯的过程。
将整个 dfs 与回溯过程写出来:
1 → 2 → 4 → 7 → 4 → 8 → 4 → 2 → 5 → 2 → 1 → 3 → 6 → 3 → 1
这就是欧拉序了。
如何求出答案
如何求 LCA 呢?
假设我们要求 LCA(3,7) 。
那我们先把欧拉序中 3,7 第一次出现的位置 标出来。
1 → 2 → 4 → 7 → 4 → 8 → 4 → 2 → 5 → 2 → 1 → 3 → 6 → 3 → 1
LCA(3,7) 就是欧拉序标红的 3,73,7 之间深度最小的点,就是 11 。
暴力找一遍 3,73,7 之间深度最小的点肯定不行。
由于欧拉序不变,此时可以用 \text{st}st 表的方法优化,就能 O(1)O(1) 查询。
设 f[i][j] 表示欧拉序中第 ii 个点以及后面共 2^j 个点中深度最小的点。
dfs 预处理出欧拉序:
#define N 1000007
int n,m,rt;
struct edge{
int to,nxt;
}e[N<<1];
int tot,head[N];
inline void adde(int u,int v){
e[++tot]=(edge){v,head[u]};
head[u]=tot;
} int dep[N],lg[N<<1],f[N<<1][21];
int dfn[N<<1],que[N<<1],idx;
void dfs(int u,int pa)
{
dfn[u]=++idx,que[idx]=u;
dep[u]=dep[pa]+1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==pa)continue;
dfs(v,u);
que[++idx]=u;
}
}
建 st 表:
void buildst()
{
For(i,1,idx)f[i][0]=que[i];
For(j,1,20)
for(int i=1;i+(1<<j)<=idx;++i){
int f1=f[i][j-1],f2=f[i+(1<<j-1)][j-1];
f[i][j]=dep[f1]<dep[f2]?f1:f2;
}
lg[0]=-1;
For(i,1,idx)lg[i]=lg[i>>1]+1;
}
查询:
inline int getlca(int u,int v)
{
if(dfn[u]>dfn[v])swap(u,v);
u=dfn[u],v=dfn[v];
int kk=lg[v-u+1],f1=f[u][kk],f2=f[v-(1<<kk)+1][kk];
return dep[f1]<dep[f2]?f1:f2;
}
看了一下 P3379 提交记录,发现 O(logn) 的树剖跑的比这个 O(1) 还快
update :
在 某题 里把树剖 LCA 换成了 st 表求 LCA 结果快了不少。
看来 st 表求 LCA 可以在查询次数多的情况下 用来卡常。
欧拉序求LCA的更多相关文章
- LCA-RMQ+欧拉序
还是那一道洛谷的板子题来说吧 传送门 其实好几天之前就写了 结果dr实在是太弱了 没有那么多的精力 于是就一直咕咕咕了 哎 今天终于补上来了 LCA概念传送门 RMQ传送门 这个算法是基于RMQ和欧拉 ...
- hdu 2586 欧拉序+rmq 求lca
题意:求树上任意两点的距离 先说下欧拉序 对这颗树来说 欧拉序为 ABDBEGBACFHFCA 那欧拉序有啥用 这里先说第一个作用 求lca 对于一个欧拉序列,我们要求的两个点在欧拉序中的第一个位置之 ...
- Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)
题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...
- P3379 【模板】最近公共祖先(LCA)(欧拉序+rmq)
P3379 [模板]最近公共祖先(LCA) 用欧拉序$+rmq$维护的$lca$可以做到$O(nlogn)$预处理,$O(1)$查询 从这里剻个图 #include<iostream> # ...
- HDU 2586(LCA欧拉序和st表)
什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细 因为欧拉序中的两点之间,就是两点遍历的过程,所以只 ...
- lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增
https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...
- dfs序和欧拉序
生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解. 一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...
- [BZOJ3772]精神污染 主席树上树+欧拉序
3772: 精神污染 Time Limit: 10 Sec Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...
- 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈
[BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...
- 图论——Tarjan 初步 DFS序+时间戳+欧拉序
一.什么是DFS序: DFS序是按照先序遍历,先遍历根节点然后依次遍历左子树,右子树的过程,每次遇到新的节点就把新访问节点加到序列中,代码如下: int DFSrk[100000]; int cnt= ...
随机推荐
- 3D降噪_运动估计块运动匹配
运动估计 运动估计是视频去噪技术的重要组成之一,计算相邻两帧视频序列各像素的相对运动偏移量,从而得到其运动轨迹. 点 ( i , j ) (i,j) (i,j)和 ( x , y ) (x,y) (x ...
- ls 和 du显示文件大小不一样
查看当前文件系统的磁盘使用 df -k / Filesystem 1K-blocks Used Available Use% Mounted on /dev/nvme0n1p2 97844508 37 ...
- 2021-7-29 MySql多表查询详解
多表连接 左连接:返回第一张表的所有数据项然后拼接第二张表(左表全有,右表对应左表才有) 右连接:返回第二张表的所有数据项然后拼接第一张表(右表全有,左表对应右表才有) 内连接:返回两张表数据相等的数 ...
- Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用
Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用 1. 什么是PhysicsRaycaster组件? PhysicsRaycaster是Unity UGUI中的 ...
- redis的一些简单操作(针对key)
redis默认16个数据,默认使用0号 select为切换数据库的关键字 select 1 切换数据库 设置值 set k1 lucy key为 k1 value 为 lucy 查看全 ...
- 叶绿素含量测定仪SPAD-502怎么使用?
本文介绍基于SPAD-502叶绿素仪测定植被叶片叶绿素含量的方法. SPAD-502是由日本柯尼卡美能达(Konica Minolta)株式会社生产的轻便.手持式叶绿素仪,可以在不破坏作物的情 ...
- tf.feature_column.input_layer 特征顺序问题
先说结论 tf.feature_column.input_layer()的api,会对传入的feature_columns进行排序,并不是按照输入顺序进行组织,排序依据基于feature_column ...
- 需求太多处理不过来?MoSCoW模型帮你
一.MoSCoW模型是什么 MoSCoW模型是在项目管理.软件开发中使用的一种排序优先级的方法,以便开发人员.产品经理.客户对每个需求交付的重要性达成共识. MoSCoW是一个首字母缩略词,代表: M ...
- .NET爬取美图官网首页数据实战
前言: 在当今信息化社会,网络数据分析越来越受到重视.而作为开发人员,掌握一门能够抓取网页内容的语言显得尤为重要.在此篇文章中,将分享如何使用 .NET构建网络抓取工具.详细了解如何执行 HTTP 请 ...
- 一文读懂LockSupport
阅读本文前,需要储备的知识点如下,点击链接直接跳转. java线程详解 Java不能操作内存?Unsafe了解一下 LockSupport介绍 搞java开发的基本都知道J.U.C并发包(即java. ...