Dfs 序 LCA

普通倍增求 LCA 的时代早已过去!时空大常数并且代码大坨的四毛子树和 Tarjian 的光辉渐渐褪去。新的时代,就要有新的 LCA 求法!dfn 序求 LCA,同时兼备码量巨小,常数(特别是空间常数)巨小,查询 O(1) ,好理解,等众多好处,将 DFS 序求 LCA 发扬光大,让欧拉序求 LCA 成为时代的眼泪!

大量参考:https://www.luogu.com.cn/article/pu52m9ue

假设现在在求 \(u\),\(v\) 的 LCA \(d\),可以发现其在 dfs 序下有许多性质。

不妨让 \(dfn_u < dfn_v\),显然 u 不会是 v 的儿子。可以分类讨论:

  1. u 不是 v 的祖先。那么 dfs 时就是 \(d -> u -> d -> v\) 的顺序,这里虽然经过了 d ,但是显然不会给 d 编号。考虑 d -> v 路径上,只有点 d 不在遍历的过程中标号,假设 d -> v 路径上第二个点为 v',可以发现 v' 是 dfs 序在 \([dfn_u,dfn_v]\) 之间深度最小的点。所以只需要找到 dfs 序在 \([dfn_u,dfn_v]\) 之间深度最小的点 v',它的父亲就是 d。

  2. u 是 v 的祖先。显然可以判断子树的包含关系,但是有一种更加简洁的方法,那就是找到 dfs 序在 \([dfn_{u + 1},dfn_v]\) 之间深度最小的点 v',它的父亲就是 d。这对于情况 1 其实也是适用的。

使用 st 表维护区间深度最小的点,复杂度 \(O(n\log n)~O(1)\)。

还要记得特判 u == v 的边界情况。

代码短小精悍:

void dfs(int u, int f) {
stmin[dfn[u] = ++ DFN][0] = f;
for(int v : e[u]) if(v ^ f) dfs(v, u);
}
inline int dfnmin(int x, int y) {return dfn[x] < dfn[y] ? x : y;}
void preworkstmin() {For(i, 1, n) for(int j = 1; i - (1 << j) + 1 >= 1; ++j) stmin[i][j] = dfnmin(stmin[i][j - 1], stmin[i - (1 << (j - 1))][j - 1]);}
inline int LCA(int x, int y) {
if(x == y) return x;
if((x = dfn[x]) > (y = dfn[y])) swap(x, y);
int s = __lg(y - x ++); // y - (x + 1) + 1
return dfnmin(stmin[x + (1 << s) - 1][s], stmin[y][s]);
}
int main() {
n = read(), m = read(), rt = read();
For(i, 1, n - 1) {
int u = read(), v = read();
e[u].pb(v), e[v].pb(u);
}
dfs(rt, 0), preworkstmin();
For(i, 1, m) wt(LCA(read(), read()));
return 0;
}

O(1) Dfs 序 LCA的更多相关文章

  1. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  2. HDU 3966 dfs序+LCA+树状数组

    题目意思很明白: 给你一棵有n个节点的树,对树有下列操作: I c1 c2 k 意思是把从c1节点到c2节点路径上的点权值加上k D c1 c2 k 意思是把从c1节点到c2节点路径上的点权值减去k ...

  3. bzoj2819 DFS序 + LCA + 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2819 题意:树上单点修改及区间异或和查询. 思维难度不高,但是题比较硬核. 整体思路是维护每一个结 ...

  4. 蓝皮书:异象石 【dfs序+lca】

    题目详见蓝皮书[算法竞赛:进阶指南]. 题目大意: 就是给你一颗树,然后我们要在上面进行三种操作:  1.标记某个点  或者  2.撤销某个点的标记  以及   3.询问标记点在树上连通所需的最短总边 ...

  5. HDU 6203 ping ping ping(dfs序+LCA+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连 ...

  6. HDU 5296 Annoying problem dfs序 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5296 Description Coco has a tree, w ...

  7. Gym 101142G : Gangsters in Central City(DFS序+LCA+set)

    题意:现在有一棵树,1号节点是水源,叶子节点是村庄,现在有些怪兽会占领一些村庄(即只占领叶子节点),现在要割去一些边,使得怪兽到不了水源.给出怪兽占领和离开的情况,现在要割每次回答最小的割,使得怪兽不 ...

  8. POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

    Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 D ...

  9. BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】

    题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...

  10. BZOJ 4999: This Problem Is Too Simple! DFS序+LCA+树状数组+离线

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) , ...

随机推荐

  1. leetcode 224

    简介 简易计算器 一时半会儿没写出来,看了官方题解. 感觉思路是遇到 ( 前一个操作符号,入栈,遇到 ) 栈中弹出操作符号 遇到 + 符号为栈顶符号 遇到 - 符号为 栈顶符号的反符号 官方使用栈来保 ...

  2. 面向 Git 用户的 jujutsu 使用入门

    在软件开发领域,版本控制是协作的基石. Git作为当前主流工具,虽功能强大但设计理念可追溯至2005年,其复杂的命令集和冲突处理机制常令开发者困扰.近年来,新兴工具--比如Jujutsu(jj)和Pi ...

  3. MySQL数据迁移到SQLServer数据库

    随着云计算技术的发展以及大数据时代的到来,越来越多的企业开始寻求更加高效.安全的数据管理解决方案.MySQL作为一种开源的关系型数据库管理系统,在互联网应用开发中占据了极其重要的位置:而另一方面,Mi ...

  4. 扣子Coze智能体实战:自动化拆解抖音对标账号,输出完整分析报告(喂饭级教程)

    大家好,我是汤师爷,专注AI智能体分享,致力于帮助100W人用智能体创富~ 作为短视频创作者,你是否经常遇到这样的困扰: 花了大量时间创作内容,却总是无法获得理想的播放量? 看到其他账号快速增长,却不 ...

  5. 理解C语言中字符串常量的本质

    C语言中字符串常量的本质表示其实是一个地址,C语言中编译器会给字符串常量分配地址,字符串常量的本质表现是代表它的第一个字符的地址 给字符串分配地址 char *s; s= "hello&qu ...

  6. linux服务器更换主板后无法识别网卡(网卡启动失败)解决办法

    在我的超算集群里,有台服务器故障报修,主板坏了,更换主板后,无法识别网卡,用命令ifconfig -a 查看只显示lo loopback 127.0.0.1,以及eth7,eth8,eth9等没有网卡 ...

  7. 控制一行显示多少个Item

    .project-list-ul { display: grid; margin-top: 5px; grid-template-columns: repeat(7, minmax(0,1fr)); ...

  8. js函数中的this

    特殊对象this 一.标准函数中,this引用的是把函数当成方法调用的上下文对象 window.color = 'red'; let o={ color:'blue' } function sayCo ...

  9. Vue 缓存之坑,变量赋值方式和响应式数据

    const { IsSuperAdmin } = useUserStore().userInfo; /** * 获取后台动态路由数据,解析并注册到全局路由 * * @returns Promise&l ...

  10. 【PostgreSQL 17】9 集合运算符

    一.并集 UNION UNION ALL 不会去重,效率更高 SELECT emp_id FROM excellent_emp WHERE year = 2018 UNION SELECT emp_i ...