欧拉序求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= ...
随机推荐
- linux系统下python中的tkinter库
打开终端,输入如下命令: sudo apt-get update sudo apt-get install python3-tk
- Gin+Xterm.js实现远程Kubernetes Pod(一)
Xterm.js简介 xterm.js (https://xtermjs.org/)是一个开源的 JavaScript 库,它模拟了一个终端接口,可以在网页中嵌入一个完全功能的终端.这个库非常灵活,并 ...
- Codeforces 1855B:Longest Divisors Interval 最长的连续约数区间
1855B.Longest Divisors Interval Description: 对于一个整数 \(n\) \((1\leq n \leq 10^{18})\),找到一段最长的区间\([l,r ...
- TCP如何实现可靠传输、流量控制、拥塞控制
上一篇文章中讲述了TCP首部的存储的数据,这一篇来聊聊这些数据帮助TCP实现一些特性. 可靠传输 TCP传输会保障数据的可靠和完整,如果数据传输过程丢失了,会重新传输. 保障的第一种协议方式是 停止等 ...
- 【Hexo】插件推荐以及使用小技巧
目录 插件推荐 hexo-deployer-git hexo-word-counter hexo-abbrlink hexo-generator-sitemap 小技巧 自定义提交信息 参考资料 He ...
- 【微信自动化】使用c#实现微信自动化
引言 上个月,在一个群里摸鱼划水空度日,看到了一个老哥分享的一个微信自动化的一个类库,便下载了他的Demo,其本意就是模拟鼠标来操作UI,实现UI自动化:然后自己在瞎琢磨研究,写了一个简单的例子,用来 ...
- 为何每个开发者都在谈论Go?
本文深入探讨了Go语言的多个关键方面,从其简洁的语法.强大的并发支持到出色的性能优势,进一步解析了Go在云原生领域的显著应用和广泛的跨平台支持.文章结构严谨,逐一分析了Go语言在现代软件开发中所占据的 ...
- jquery实现表格导出Excel
使用jQuery,jszip.js,FileSaver.js,excel-gen.js插件直接将网页中的table表格导出到本地Excel文件,而不需要经过后台. 导出结果: 实现步骤: 1.进入相关 ...
- KRPano多屏互动原理
KRPano可以实现多个屏幕之间的同步显示,主要应用到Websocket技术进行通信. 在控制端,我们需要发送当前KRPano场景的实时的视角和场景信息,可以使用如下的代码: embedpano({ ...
- 小札 Combinatorics & Inclusion-Exclusion Principle 1
「codeforces - 340E」Iahub and Permutations link. 把 \(1,\dots,n\) 中剩下没被固定的数的数量记作 \(s\),再把这其中不担心有会填到自己身 ...