用樹鏈剖分來寫LCA

2022-03-27 08:32:49 字數 818 閱讀 3794

當兩個點在一條鏈上,它們的lca就是深度較小的那個點。

於是這種樹鏈剖分寫lca的思想就是把要求的兩個點想辦法靠到一條鏈上。

而且要靠到盡量更優的一條鏈上(重鏈)。 

做法:預處理出每棵樹上的重鏈(size大的),每個點求出乙個top,代表與這個點能靠到最近的一條重鏈的位置。

求lca時兩個點分別向各自top移動,直到兩個點到一條鏈上,輸出深度較小的

細節見**

#include#include

#define maxn 500001

using

namespace

std;

struct edgeb[maxn*2

];struct nodea[maxn];

intcnt,n,m,x,y,l,root;

void connect(int x1,int

x2);

a[x1].last=cnt;

}void dfs1(int

x1)                  //第一次dfs預處理size、深度,求出重鏈 (變數名錯了 h就是size)

}}void dfs2(int

x1)                 //第二次dfs預處理top

int lca(int x1,int

x2)

return a[x1].depthx1:x2;

}int

main()

dfs1(root);

dfs2(root);

while(m--)

return0;

}

Lca樹鏈剖分法

樹鏈剖分各陣列的作用 son 最重的兒子節點,即節點最多的那個 bulk 所有兒子節點的總和 包括兒子的兒子 dep 該節點的深度 ft 該節點的父親 top 鏈的最上方的節點 首先dfs預處理出前面的四個陣列。然後第二個dfs進行剖分,預處理出最後乙個陣列。例子 此時son 1 3 因為bulk ...

LCA 樹鏈剖分

剛打完lca板子,寫個東西記下 dfs第一遍求出 結點i的深度,以i為根的子樹大小,結點i的父親,並求出重鏈 dfs第二遍求出 結點i所在重鏈的鏈頂 如果在重鏈上 開始lca,兩個點往上找,深度大的點就往上跳,這個點如果在重鏈上,就跳到所在重鏈的鏈頂的父親處,在輕鏈上,就直接跳到自己父親上 洛谷lc...

樹鏈剖分(1) 樹剖求LCA

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