LCA倍增法模板

2021-06-20 05:48:41 字數 876 閱讀 5074

deg其實應該寫成depth吧,存的是每個結點的深度,dfs的過程是為了處理出每個結點的深度,用遞推式計算出fa[u][i],其中f[u][i]表示u的第2^i個祖先;

基本思想是:

d[i] 表示 i節點的深度, p[i,j] 表示 i 的 2^j 倍祖先

那麼就有乙個遞推式子 p[i,j]=p[p[i,j-1],j-1]   

這樣子乙個o(nlogn)的預處理求出每個節點的 2^k 的祖先   

然後對於每乙個詢問的點對a, b的最近公共祖先就是:  

先判斷是否 d[x] < d[y] ,如果是的話就交換一下(保證 x 的深度大於 y 的深度)

然後把 x 調到與 y 同深度, 同深度以後再把a, b 同時往上調,調到有乙個最小的j

滿足p[x,j]!=p[y,j] (x,y是在不斷更新的), 最後再把(x,y)往上調 (x=p[x,0], y=p[y,0])

乙個乙個向上調直到x = y, 這時 x或y 就是他們的最近公共祖先

#include #include #include #include #include #include using namespace std;

const int maxn=200020;

int head[maxn],tol,deg[maxn],fa[maxn][23];

struct node

edge[20*maxn];

void add(int u,int v)

void dfs(int u,int pre)

}int lca(int x,int y)

int main()

dfs(1,1);

// for(i=1;i<=n;i++)cout<>i>>j;

cout<

倍增LCA模板

注意!本篇題解不適合初學lca的同學學習,因為我講的很爛很不清楚。倍增,顧名思義,就是成倍增加的意思。我們知道,任何乙個數字都可以表示成二進位制。那麼對於一條長度為n的鏈,我們總是可以跳大概logn次到達最後。對於鏈上任意一點,我們都可以在大概logn的複雜度下詢問到,其實倍增的思路就是二分,和快速...

POJ 1330(LCA 倍增法模板)

題意 q次詢問求兩個點u,v的lca 思路 lca模板題,首先找一下樹的根,然後dfs預處理求lca u,v ac 1 include2 include3 include4 include5 include 6 include 7 include8 include9 include10 using ...

模板 LCA 最近公共祖先 倍增法

2019 11 07 09 25 45 c.樹之呼吸 叄之型 樹上兩點路徑長度 time limit 1000 ms memory limit 32768 k total submit 7 4 users total accepted 2 2 users special judge no descr...