LCA 樹鏈剖分

2021-08-28 17:01:32 字數 1024 閱讀 1984

剛打完lca板子,寫個東西記下

dfs第一遍求出 結點i的深度, 以i為根的子樹大小, 結點i的父親, 並求出重鏈

dfs第二遍求出 結點i所在重鏈的鏈頂(如果在重鏈上)

開始lca,兩個點往上找,深度大的點就往上跳,這個點如果在重鏈上,就跳到所在重鏈的鏈頂的父親處,在輕鏈上,就直接跳到自己父親上

**:(洛谷lca板子題)

#include

#define size 500000

using

namespace std;

int n, m, root, x, y, len;

int f[size +30]

, dep[size +30]

, siz[size +30]

, son[size +30]

, top[size +30]

, fa[size +30]

;struct edge e[size *4+

30];inline

void

addedge

(int u,

int v)

; f[u]

= len;

}inline

void

dfs1

(int s)}}

inline

void

dfs2

(int s)

intlca

(int a,

int b)

if(dep[a]

>= dep[b]

)return b;

else

return a;

}int

main()

dep[root]=1

;dfs1

(root)

;dfs2

(root)

;for

(int i =

1; i <= m;

++i)

return0;

}

樹鏈剖分求LCA

這裡先推薦兩道練習的裸題 首先是求點 codevs4605 lca 就是求兩個點的公共祖先,每次詢問xor上上乙個詢問的答案。先是兩遍dfs dfs1 把dep siz son求出來 dfs2 求出top和w siz v 表示以v為根的子樹的節點數 dep v 表示v的深度 根深度為1 top v ...

樹鏈剖分求lca

題目描述 給一棵有根樹,以及一些詢問,每次詢問樹上的2 個節點a b,求它們的最近公共祖先.輸入第一行乙個整數n.接下來n 個數,第i 個數fi 表示i 的父親是fi.若fi 0,則i 為樹根.接下來乙個整數m.接下來m 行,每行2 個整數a b,詢問節點 a xor lastans bxor la...

樹鏈剖分(1) 樹剖求LCA

先看乙個樹剖的經典應用 初始化 先dfs一遍子樹,統計出每乙個點x的重兒子son x 和以x為根節點的子樹的大小siz x 這裡選擇x中子樹大小最大的兒子作為它的重兒子,第二遍dfs劃分樹鏈 重兒子與其父親節點劃分到一條鏈。其他的兒子為x的輕兒子,但屬於新的鏈的頂端元素。void dfs1 int ...