lca倍增演算法模板

2021-07-22 14:47:07 字數 1247 閱讀 5226

時間限制: 1 sec  

記憶體限制: 128 mb

提交: 244  

解決: 36

[ 提交][

狀態]給一棵樹, 節點數為n(1 <= n <= 250,000), 和q(0 <= q <= 100,000)個詢問, 對於每個詢問求出所求兩點的最近公共祖先

第一行: 節點數n

以下n行, 第i + 1行: 點i的父親節點father[i] (假定根的父親是0)

下一行為詢問數q

每個詢問包含兩個整數i, j你的程式應按照詢問的次序回答出所求兩點的最近公共祖先

共n行, 第i行: 第i個詢問的答案

1201

1122

3388

91055 12

12 7

9 12

10 12

12 12

138

1012

倍增演算法:主要分兩步。

第一步:將兩個節點"竄"到乙個深度

第二步:兩個節點一起"竄"到他們的lca(最近公共祖先)。

'竄'的操作,如果你每個節點一下,一下,一下的竄,會非常慢。。所以就有了倍增,要一次竄2^n個節點。當然如果過頭了就少竄一點。如果你寫過01

揹包,它的思路和2進製拆包很像。

看起來好像很簡單的樣子》-《**如下(帶注釋)

#include#include#include#include#include#include#includeusing namespace std;

const int maxn=250020;

int n,q;

int g[100][100],ne,root;

int p[maxn][20];//p[i][j]表示i結點的第2^j祖先

int deep[maxn];//i的深度

int use[1000][1000];

void build(int x)//處理樹深度

} void pre()//處理祖先

} return p[a][0];//即正好竄到兩個子樹上,最近祖先為它的j=0的祖先

}int main()

p[1][0]=-1;

deep[1]=1;

build(1);

pre();

for(int i=1;i<=q;i++)

return 0;

}

倍增LCA模板

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

LCA倍增法模板

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...

倍增求lca(模板)

定義 lca,最近公共祖先,是指一棵樹上兩個節點的深度最大的公共祖先。也可以理解為兩個節點之間的路徑上深度最小的點。我們這裡用了倍增的方法求了lca。我們的基本的思路就是,用dfs遍歷求出所有點的深度。f i j 陣列用來求的是距離節點i,距離2 j的祖先。可以知道,f i 0 就是它的直接父親。然...