LCA 最近公共祖先 學習筆記

2022-10-11 09:48:11 字數 746 閱讀 3439

lca指最近公共祖先。他有許多的求法和應用。

首先最簡單的:跳到同一深度後,再一起向上跳,跳到同一節點為止。

這個方法時間複雜度最壞為\(o(n)\),如果不是乙個老善人是不會讓你過的。

如何優化這個方法呢?我們可以試試倍增,每次上跳多個節點,這樣時間複雜度就只有\(\log n\)了。

上p3379**,可以結合**食用:

#includeusing namespace std;

int n,q,head[500001],father[500001][21],tot,h[500001]= ,s;

inline void read(int &x)

while(chc>='0'&&chc<='9')

x=dat*oko;

}struct tu edge[1000001];

void insert(int x,int y)

void dfs(int x,int fa) }}

int lca(int x,int y)

} if(x==y)return x;

int p=0;

for(int i=20;i>=0;i--)

} return father[y][0];

}int main() \)為\(d_x+d_y-2\times d_\)

2.樹上區間加,附查詢

如果動態就要樹剖或lct,但靜態可用樹上差分。

具體在\(x,y\)都加,\(lca\)位置將其抵消。

最近公共祖先(LCA) 學習筆記

顧名思義,就是兩個結點的最近公共父結點 這裡運用了倍增的思路,當你想要乙個個的往上遞增時,複雜度很高,可以把要遞增的數量換成二進位制表示 因為任意乙個數都可以由二進位制數相加得到 比如11,可以由 2 3 8,2 1 2,2 0 1,相加而成 所以11這個數可以先加8,在加2,在加1得到 這裡有兩個...

最近公共祖先 LCA 最近公共祖先

直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...

最近公共祖先 最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...