樹鏈剖分學習筆記

2022-10-09 08:30:10 字數 1002 閱讀 3823

樹鏈剖分用於將樹分割成若干條鏈的形式,以維護樹上路徑的資訊。

樹鏈剖分有多種形式,如重鏈剖分、長鏈剖分等,通常說的樹鏈剖分指重鏈剖分。

首先給出一些定義:

(圖源:oi-wiki)

跑兩個 dfs ,第乙個跑出來子樹大小,深度,父節點和重子節點,第二個 dfs 優先擴充套件重子節點,記錄新編號和新點權,這樣能保證先剖出來的一定是重鏈。

int hson[maxn], // 重子節點

fa[maxn], // 父節點

cnt[maxn], // 子樹大小

dep[maxn], // 深度

val[maxn], // val[i]表示初始編號i的點的點權

top[maxn], // 所在鏈的頂

id[maxn], // 新編號(dfn序)

a[maxn]; // 新編號為i的點的點權

void dfs(int u,int f)

}void dfs1(int u,int f,int t)

時間複雜度:\(o(n)\)

lca每次把重鏈頂深度較大的點向上跳重鏈,如果兩個點在同一條鏈上,就直接返回深度更小的。

int lca(int x,int y)

路徑上的點權修改

過程和求 lca 類似,由於每一條重鏈上的 dfn 值都是連續的,可以用線段樹修改,在向上跳的過程中把每條重鏈都修改了,最後修改剩餘部分。

void update_chain(int x,int y,int k)

路徑上的點權和查詢

在向上跳的時候答案加上每條重鏈的和,最後加上剩餘部分。

int query_chain(int x,int y)

樹鏈剖分學習筆記

寫 又犯了很sb的錯誤,線段樹寫錯了。好像每次都會把r l 1寫成l r 1,然後就只有20分。寫的比較醜,壓了壓之後190行。基本上是我打過的最長的乙個模板了 然後簡單介紹一下樹剖吧。樹鏈剖分,就是把樹剖分成鏈,然後用資料結構來維護這些鏈,使得詢問 修改的複雜度達到o logn o l ogn 不...

樹鏈剖分學習筆記

樹鏈剖分 mod estc oder modestcoder modest code r如果你是重兒子,你就在重路徑上。如果你是輕兒子,暴力沿著祖先向上爬最多log nlogn logn 次就可以遇到重路徑。或者到根 而樹上操作基本就是找祖先 也許有人喜歡我的碼風 include include d...

樹鏈剖分學習筆記

前言 書上只講了重鏈剖分,菜雞也只會這一種,想看其他的是別想了。要會樹鏈剖分,首先你需要了解一些概念。我們把乙個節點的所有兒子節點中子樹節點數最大的稱為重兒子,也就是size最大的子節點。size的定義我在講換根dp時說過,因此不再贅述。對於每個節點的重兒子,我們用 son x 來記錄它,父親節點到...