当前位置: 首页 > news >正文

【模板】最近公共祖先(LCA)【牛客tracker 每日一题】

【模板】最近公共祖先(LCA)

时间限制:3秒 空间限制:256M

网页链接

牛客tracker

牛客tracker & 每日一题,完成每日打卡,即可获得牛币。获得相应数量的牛币,能在【牛币兑换中心】,换取相应奖品!助力每日有题做,丰盈牛币日益多!

题目描述

给定一棵由N NN个点组成的以点R RR为根的多叉树,有M MM次询问,每次给定两个节点u , v u,vu,v,你需要求出这两个节点的最近公共祖先

【名词解释】

最近公共祖先(L C A LCALCA):两个节点在树中深度最大的共同祖先节点。

输入描述:

第一行包含三个正整数N , M , R ( 1 ≦ R ≦ N ≤ 5 × 10 5 , 1 ≦ M ≦ 5 × 10 5 ) N,M,R(1≦R≦N≤5×10^5,1≦M≦5×10^5)N,M,R(1RN5×105,1M5×105),分别表示树的结点个数、询问的个数和树根结点的序号。

接下来N − 1 N−1N1行每行包含两个正整数x , y x,yx,y,表示x xx结点和y yy结点之间有一条直接连接的边(数据保证可以构成树)。

接下来M MM行每行包含两个正整数a , b ( 1 ≦ a , b ≦ N ) a,b(1≦a,b≦N)a,b1a,bN,表示询问a aa结点和b bb结点的最近公共祖先。

输出描述:

输出包含M MM行,每行包含一个正整数,依次为每一个询问的结果。

示例1

输入:

5 5 4 3 1 2 4 5 1 1 4 2 4 3 2 3 5 1 2 4 5

输出:

4 4 1 4 4

说明:

该树结构如下:

第一次询问:2 , 4 2,42,4的最近公共祖先,故为4 44

第二次询问:3 , 2 3,23,2的最近公共祖先,故为4 44

第三次询问:3 , 5 3,53,5的最近公共祖先,故为1 11

第四次询问:1 , 2 1,21,2的最近公共祖先,故为4 44

第五次询问:4 , 5 4,54,5的最近公共祖先,故为4 44

故输出依次为4 , 4 , 1 , 4 , 4 4,4,1,4,44,4,1,4,4

解题思路

本题是最近公共祖先(LCA)模板题,针对N , M ≤ 5 × 10 5 N,M \le 5 \times 10^5N,M5×105的大数据规模,采用倍增法实现高效求解。暴力法时间复杂度过高无法通过,倍增法通过预处理每个节点的2 k 2^k2k级祖先与节点深度,将单次查询复杂度降至O ( log ⁡ N ) O(\log N)O(logN)。首先构建树的邻接表,通过DFS递归遍历整棵树,初始化父节点与倍增数组;查询时,先将两个节点跳至同一深度,再同步倍增上跳,直至找到最近公共祖先。算法预处理复杂度O ( N log ⁡ N ) O(N \log N)O(NlogN),整体效率完美适配题目数据约束。

总结

核心逻辑:倍增法预处理节点的多级祖先信息,通过快速跳步实现LCA的高效查询。
关键操作:邻接表建图、DFS预处理深度与倍增表、深度对齐+倍增跳步求解。
效率保障:对数级的预处理与查询复杂度,轻松应对5 × 10 5 5 \times 10^55×105级别的节点与询问数量。

代码内容

#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'typedeflonglongll;typedefunsignedlonglongull;typedefvector<vector<ll>>vvt;typedefpair<ll,ll>pll;constll N=500010;constll INF=1e18;constll M=1e6+10;constll mod=1e9+7;constll LOG=25;ll n,m,r;vector<ll>g[N];ll depth[N];ll st[N][LOG];voiddfs(ll u,ll p){st[u][0]=p;for(ll i=1;i<LOG;i++){st[u][i]=st[st[u][i-1]][i-1];}for(ll i:g[u]){if(i==p){continue;}depth[i]=depth[u]+1;dfs(i,u);}}llLCA(ll u,ll v){if(depth[u]<depth[v])swap(u,v);ll diff=depth[u]-depth[v];for(ll i=0;i<LOG;i++){if(diff&(1LL<<i))u=st[u][i];}if(u==v)returnu;for(ll i=LOG-1;i>=0;i--){if(st[u][i]!=st[v][i]){u=st[u][i];v=st[v][i];}}returnst[u][0];}voidsolve(){cin>>n>>m>>r;for(ll i=1;i<n;i++){ll x,y;cin>>x>>y;g[x].push_back(y);g[y].push_back(x);}depth[r]=0;dfs(r,r);while(m--){ll x,y;cin>>x>>y;cout<<LCA(x,y)<<endl;}}intmain(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);solve();return0;}
http://www.jsqmd.com/news/813446/

相关文章:

  • Kotlin Multiplatform (KMP) 跨端改造实战:聚焦性能与功耗优化的深度解析
  • Windows系统下PyTorch三维处理利器Kaolin的安装与配置全攻略
  • 深度优化之道:Android应用性能与功耗优化实战指南
  • TimeGen3.2实战指南:从零绘制专业硬件时序图
  • 自托管AI工作空间Llama Workspace:企业级部署与核心架构解析
  • 用Python处理医学影像?从零开始搞定BraTS 2018的.nii.gz文件(附完整代码)
  • Android/鸿蒙双平台性能与功耗优化实战指南:从原理到实践
  • 别再人云亦云了!实测对比ptmalloc、jemalloc、tcmalloc,你的项目到底该选谁?
  • 如何轻松解锁Cursor Pro功能:一键激活与无限使用的完整指南
  • Flutter应用开发中的性能与功耗优化策略
  • AI Agent驱动桌面自动化:cua_desktop_operator_skill实战指南
  • 工业4.0时代:DevOps与平台工程如何重塑软硬件协同开发
  • 2026年评价高的鄱阳毛坯房装修公司/装修公司综合评价公司 - 行业平台推荐
  • 5分钟掌握B站视频数据批量采集:免费开源工具Bilivideoinfo终极指南
  • Intel AMX加速器THOR漏洞:矩阵运算中的侧信道风险
  • 基于大语言模型的AI狼人杀游戏:双层角色扮演与模型竞技场设计
  • 2026年比较好的自住轻钢别墅/欧式轻钢别墅/云南轻钢别墅推荐榜单公司 - 品牌宣传支持者
  • 外卖点餐连锁店餐饮生鲜奶茶外卖店内扫码点餐源码同城外卖校园外卖源码的扫码逻辑
  • AntiDupl.NET:免费开源图片去重工具终极指南
  • FPGA与CPLD选型及设计实战:从架构差异到图像处理实现
  • 索尼战略转型:从协同效应幻灭到聚焦核心能力的商业启示
  • 开源项目chatgpt-artifacts:为ChatGPT添加Claude式文件生成功能
  • 基于Go语言构建高可靠客户端:OpenClaw Client框架解析与实践
  • 半导体行业如何应对政策不确定性:从游说策略到企业决策
  • 手把手教你用UE5 C++复刻《只狼》式动态攀爬:不止于ALS V4的拓展思路
  • VMware macOS 虚拟机终极解锁指南:Unlocker 3.0 完整使用教程
  • 为什么你的嵌入式调试总出问题?可能是缺了这个带隔离的JLink方案
  • 别再死记硬背公式了!用‘井字棋’和‘抢30’游戏带你直观理解巴什博弈(Bash Game)
  • DCRAW 实战:从命令行到线性工作流的深度解析
  • 从弹簧振子到无人机建模:手把手用Matlab ode45搭建你的第一个动力学仿真模型