使用欧拉序 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. 前后端分离实现注册+登录(Vue3.0 + Django3.2)

    博客地址:https://www.cnblogs.com/zylyehuo/ 一.使用 vite+webstorm 搭建 Vue 环境,构建前端 1.结构树 2.main.js import { cr ...

  2. PHP echo 和 print 语句

    在 PHP 中,有两种基本的输出方法:echo 和 print. PHP echo 和 print 语句 echo 和 print 之间的差异: echo - 能够输出一个以上的字符串 print - ...

  3. java中Object 类

    一. Object类简介 Object类是Java.java.lang包下的核心类,Object类是所有类的父类,任何一个类如果没有明确的继承一个父类的话,那么它就是Object的子类: (使用无需导 ...

  4. React: 路由重定向

    解决方案 参考链接 https://v5.reactrouter.com/web/example/route-config

  5. Singleton Pattern 单例模式简介与 C# 示例【创建型】【设计模式来了】

    〇.简介 1.什么是单例模式? 一句话解释:   单一的类,只能自己来创建唯一的一个对象. 单例模式(Singleton Pattern)是日常开发中最简单的设计模式之一.这种类型的设计模式属于创建型 ...

  6. 【教程】青少年CTF机器人使用教程

    前言 本期教程适用于版本号为2.0.1-Beta的青少年CTF机器人,其他版本可能与当前版本不同. 由于之前版本的机器人重构,所以我们细化了本次的机器人逻辑,并且对机器人的功能进行了一些升级. 机器人 ...

  7. PoW是什么?

    PoW是什么? 工作量证明(proof of work,PoW)是一种用于确认和验证区块链交易和新区块有效性的共识算法.区块链中常见的工作量证明算法包括比特币的SHA-256.以太坊的Ethash.莱 ...

  8. redis数据持久化之RDB和AOF

    前言 redis虽然是内存缓存程序,但是可以将内存中的数据保存到硬盘上,从而实现数据保存.目前有两种redis数据持久化方式,分别是RDB和AOF. RDB模式 RDB之简介 RDB(redis da ...

  9. CentOS7挂载NTFS格式的硬盘

    前言 一些NTFS格式的移动硬盘或U盘插在服务器上可能不会自动挂载,本文为手动挂载的步骤. 步骤 安装相关程序: yum install -y ntfs-3g 使用一些命令查看需要挂载的分区 # 查看 ...

  10. ATtiny88初体验(三):串口

    ATtiny88初体验(三):串口 ATtiny88单片机不包含串口模块,因此只能使用软件方式模拟串口时序. 串口通信时序通常由起始位.数据位.校验位和停止位四个部分组成,常见的配置为1位起始位.8位 ...