惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
S
Securelist
P
Proofpoint News Feed
H
Help Net Security
S
Schneier on Security
T
Tenable Blog
C
Cisco Blogs
S
Security @ Cisco Blogs
博客园 - 司徒正美
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
Google DeepMind News
Google DeepMind News
C
Cybersecurity and Infrastructure Security Agency CISA
Google Online Security Blog
Google Online Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hacker News: Ask HN
Hacker News: Ask HN
NISL@THU
NISL@THU
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
W
WeLiveSecurity
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Jina AI
Jina AI
腾讯CDC
WordPress大学
WordPress大学
Simon Willison's Weblog
Simon Willison's Weblog
Vercel News
Vercel News
小众软件
小众软件
N
Netflix TechBlog - Medium
有赞技术团队
有赞技术团队
AWS News Blog
AWS News Blog
雷峰网
雷峰网
Forbes - Security
Forbes - Security
The Hacker News
The Hacker News
博客园 - 聂微东
F
Full Disclosure
量子位
Scott Helme
Scott Helme
宝玉的分享
宝玉的分享
A
About on SuperTechFans
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Schneier on Security
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
K
Kaspersky official blog
AI
AI
SecWiki News
SecWiki News
Webroot Blog
Webroot Blog
Martin Fowler
Martin Fowler

Victrid's Personal Site

斯普拉遁3打工模式联机网络过程分析 DHCP无类型静态路由──一个摆设 配置透明代理,实现无感上网 Generating Unlimited Grammar: A Messenger Perspective LaTeX插入其他PDF中的矢量图 光速不变原理和迈克尔孙──莫雷实验 交大葡萄演义 调试微信内置浏览器 欧悌甫戎篇 苏格拉底的申辩篇 弥罗斯人的辩论 埃斯库罗斯作品:波斯人、阿伽门农 电路理论资料 Coronavirus: A Humanitarian Crisis 雨夜 linux配置SSR 二叉堆的实现 懒政 Placement New Flipped: A Love Story 我宁可呆在这样的疯人院里 谈新发本地病例 勇敢与智慧 Powerful but Limited Drafted VLC Libva Error Troubleshooting Ring-Fit新上手 政治艺术化与艺术政治化 动态规划——从分割等和子集入手 被背叛的革命 (1) Everything About DPT-RP1 When Using LINUX HTTP STATUS 451 二分法——重复情形 鸽巢排序与桶排序 为什么要写博客 系统更换 动窗法与前缀和——简单实践 非类型模板参数 判断的短路规则 CodeBlocks重装 C-Style String Operation
LCA 最近公共祖先
Victrid · 2020-06-03 · via Victrid's Personal Site

最近公共祖先(Lowest Common Ancestor)的定义:同一棵树的节点u,v,定义:

lca(u,v)为分别包含u、v的全部该树的子树的并集中的最小高度树的根节点。

下面介绍四种求最近公共祖先的方法。暴力法、倍增法、Tarjan算法,RMQ算法。

暴力法

标记现在的点访问过;向上跳到父节点。

重复这一过程,直到跳到的父节点被标记为访问过。

时间复杂度O(n)(还需要O(n)清除标记)。

一种不需要清除标记的优化方法:将访问标记和查询次数对应:第i次查询标记i,这样就可以不需要清除标记。

DP标记——倍增算法

标记一组f[i][j],标记i节点的上方第$2^j$个节点。

深的节点向上跳,跳到相同的高度。

可以利用DP标记向上跳:比如说深度相差7,分别跳4,2,1。

同时向上跳:同时跳到最深的不同节点,直到跳到父节点相同为止。

时间复杂度:O_{init}(nlgn),O_{query}(lgn), 空间复杂度:O(nlgn)

这是一个在线算法。

Tarjan算法

将所有的查询lca(a,e),lca(c,e),lca(d,a)建立查询集合

1
2
3
4
5
6
7
Sa={(a,e),(d,a)}

Sc={(c,e)}

Sd={(d,a)}

Se={(a,e),(c,e)}

维护并查集UFS(u)->u

一遍DFS,完成所有查询。

进入节点u:对于查询集合Su中的每一个查询lca(u,v)

  • 如果查询没有访问过,标记被访问。

  • 如果查询被访问过,lca(u,v)=UFS(v)

Union(UFS(v),UFS(father_v))->UFS(v)

这是一个离线算法。

此处的UFS为并查集:定义操作:查找find(u),并union(u,v):u<=>v

时间复杂度:O_{init}(n+m),O_{query}(n+m(lgn)), 空间复杂度:O(n)

RMQ 区间最值查询算法

区间最小值查询Range Minimum Query)的定义:对于数组list,

rmq(l,r) = min_{l<=k<r} list[k]

RMQ: Sparse Table算法

建立数组st[i][j]为区间[i,i+2^j)的区间最小值下标。

(可以递推:st[i] [j] = min{st[i][j-1],st[i+2^{j-1}][j-1]}建立)

询问:设t为r-l+1的二进制最高位数,则有

rmq(l,r) = min{st[l][t], st[r-2^t+1][t]}

因为上面的集合一定覆盖[l,r]

用RMQ解决LCA

先DFS一棵树,记录DFS顺序表为seq。

DFS顺序:DFS搜索所经过的所有节点,包括已经经过的重复节点。(长度2n-1(参考电路理论的树))

first[node]记录节点node在第一次出现的位置。

此时lca(u,v)=seq.rmq(first[u],first[v])

Ads by Google

Read our privacy policy on how these personalized advertisements are delivered to you.

For your reading experience, we provide full-text RSS feeds. Although math formulas cannot be displayed well, the interface can be adjusted as you like and there are no ads.