倍增算法
树上倍增
倍增算法就是通过倍增快速查找的算法。它在树的问题上比树链剖分处理得要快而且简单。
它的核心公式就是fa[x][j]=fa[fa[x][j-1]][j-1] / fa[x][j+1]=fa[fa[x][j]][j].为了更好地理解这个公式,我打了以下表格:
0 | 1 | 2 | 3 | |
1 | 0 | 0 | 0 | 0 |
2 | 1(1+2^0) | 0 | 0 | 0 |
3 | 2 | 1(1+2^1) | 0 | 0 |
4 | 3 | 2 | 0 | 0 |
5 | 4 | 3 | 1(1+2^2) | 0 |
6 | 5 | 4 | 2 | 0 |
7 | 6 | 5 | 3 | 0 |
8 | 7 | 6 | 4 | 0 |
9 | 8 | 7 | 5 | 1(1+2^3) |
看得出来,横行表示的是2的幂数,也就是fa[x][j]中的j。
将j和x颠倒似乎能优化。
那么每次dfs一个点的时候,我们先记录fa[x][0]为该点的直接父亲,然后将它初始化:
for (register int i=0;fa[x][i];++i) fa[x][i+1]=fa[fa[x][i]][i];
若要求两点的LCA,首先要记录它们的深度,然后倍增:
inline int LCA(int u,int v) { if(dep[u]<dep[v])swap(u,v); for(R int i=0;i<=16;i++) if((dep[u]-dep[v])&(1<<i))u=fa[u][i]; if(u==v)return u; for(R int i=16;i>=0;i--) if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i]; return fa[u][0]; }
毕竟,指数爆炸可是很快的。这是一个清清楚楚的logn的复杂度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!