使用欧拉序 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的更多相关文章

  1. LCA-RMQ+欧拉序

    还是那一道洛谷的板子题来说吧 传送门 其实好几天之前就写了 结果dr实在是太弱了 没有那么多的精力 于是就一直咕咕咕了 哎 今天终于补上来了 LCA概念传送门 RMQ传送门 这个算法是基于RMQ和欧拉 ...

  2. hdu 2586 欧拉序+rmq 求lca

    题意:求树上任意两点的距离 先说下欧拉序 对这颗树来说 欧拉序为 ABDBEGBACFHFCA 那欧拉序有啥用 这里先说第一个作用 求lca 对于一个欧拉序列,我们要求的两个点在欧拉序中的第一个位置之 ...

  3. Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)

    题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...

  4. P3379 【模板】最近公共祖先(LCA)(欧拉序+rmq)

    P3379 [模板]最近公共祖先(LCA) 用欧拉序$+rmq$维护的$lca$可以做到$O(nlogn)$预处理,$O(1)$查询 从这里剻个图 #include<iostream> # ...

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

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

  6. lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增

    https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...

  7. dfs序和欧拉序

    生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解.   一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...

  8. [BZOJ3772]精神污染 主席树上树+欧拉序

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...

  9. 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈

    [BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...

  10. 图论——Tarjan 初步 DFS序+时间戳+欧拉序

    一.什么是DFS序: DFS序是按照先序遍历,先遍历根节点然后依次遍历左子树,右子树的过程,每次遇到新的节点就把新访问节点加到序列中,代码如下: int DFSrk[100000]; int cnt= ...

随机推荐

  1. 3D降噪_运动估计块运动匹配

    运动估计 运动估计是视频去噪技术的重要组成之一,计算相邻两帧视频序列各像素的相对运动偏移量,从而得到其运动轨迹. 点 ( i , j ) (i,j) (i,j)和 ( x , y ) (x,y) (x ...

  2. ls 和 du显示文件大小不一样

    查看当前文件系统的磁盘使用 df -k / Filesystem 1K-blocks Used Available Use% Mounted on /dev/nvme0n1p2 97844508 37 ...

  3. 2021-7-29 MySql多表查询详解

    多表连接 左连接:返回第一张表的所有数据项然后拼接第二张表(左表全有,右表对应左表才有) 右连接:返回第二张表的所有数据项然后拼接第一张表(右表全有,左表对应右表才有) 内连接:返回两张表数据相等的数 ...

  4. Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用

    Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用 1. 什么是PhysicsRaycaster组件? PhysicsRaycaster是Unity UGUI中的 ...

  5. redis的一些简单操作(针对key)

    redis默认16个数据,默认使用0号 select为切换数据库的关键字 select 1  切换数据库 设置值 set k1 lucy       key为 k1  value 为 lucy 查看全 ...

  6. 叶绿素含量测定仪SPAD-502怎么使用?

      本文介绍基于SPAD-502叶绿素仪测定植被叶片叶绿素含量的方法.   SPAD-502是由日本柯尼卡美能达(Konica Minolta)株式会社生产的轻便.手持式叶绿素仪,可以在不破坏作物的情 ...

  7. tf.feature_column.input_layer 特征顺序问题

    先说结论 tf.feature_column.input_layer()的api,会对传入的feature_columns进行排序,并不是按照输入顺序进行组织,排序依据基于feature_column ...

  8. 需求太多处理不过来?MoSCoW模型帮你

    一.MoSCoW模型是什么 MoSCoW模型是在项目管理.软件开发中使用的一种排序优先级的方法,以便开发人员.产品经理.客户对每个需求交付的重要性达成共识. MoSCoW是一个首字母缩略词,代表: M ...

  9. .NET爬取美图官网首页数据实战

    前言: 在当今信息化社会,网络数据分析越来越受到重视.而作为开发人员,掌握一门能够抓取网页内容的语言显得尤为重要.在此篇文章中,将分享如何使用 .NET构建网络抓取工具.详细了解如何执行 HTTP 请 ...

  10. 一文读懂LockSupport

    阅读本文前,需要储备的知识点如下,点击链接直接跳转. java线程详解 Java不能操作内存?Unsafe了解一下 LockSupport介绍 搞java开发的基本都知道J.U.C并发包(即java. ...