樹鏈剖分入門

2022-08-24 20:09:14 字數 1260 閱讀 1902

將樹分割成多條鏈,然後用線段樹等來維護這些鏈。

樹鏈剖分的分割標準:連線乙個節點的子樹中的 「 重兒子 」 // 也就是結點最多的兒子,依次連下去。

定義:

重兒子:子樹節點的兒子

輕兒子:除了重兒子以外的兒子

重邊:父節點與重兒子組成的邊

輕邊:除重邊以外的邊

重鏈:重邊連線而成的鏈

輕鏈:輕邊連線而成的鏈

鏈頭:一條鏈上深度最小的點

對於樹鏈剖分,我們需要維護以下的陣列:

名稱含義

siz[u]

儲存以u為根的子樹節點個數

son[u]

儲存u的重兒子

top[u]

儲存u所在鏈的頂端節點

dep[u]

儲存結點u的深度值

faz[u]

儲存結點u的父親節點

dfn[u]

u的dfs序

rk[u]

u樹中的編號

dfs_1:預處理 siz, son, dep, faz陣列

void dfs1(int u, int father, int

depth)

}return

; }

dfs_2:預處理dfn, top, rk 陣列。

void dfs2(int u, int t) //

t:起始的重節點

return

; }

修改:

void modifyontree(int u, int v, int

val)

if(dep[u] >dep[v]) swap(u,v);

modify(

1, 1

, n, dfn[u], dfn[v], val);

}

查詢:

int queryontree(int u, intv) 

if(dep[u] >dep[v]) swap(u,v);

res += query(1, 1

, n, dfn[u], dfn[v]);

return

res;

}

樹鏈剖分入門

例題 poj 3237 bzoj 3083 bzoj 3531 bzoj 3589 bzoj 3626 將樹上問題通過dfs序的性質轉換為區間問題,從而對樹上修改時就可轉化為相應的區間修改。再通過引入重兒子,重鏈一系列概念將時間複雜度也變成了可以接受的層次 通過兩次dfs求出樹上一系列的資訊 voi...

樹鏈剖分入門

我學的學習資料 和 ppt 樹鏈剖分可以解決很多問題,輔助一些線段樹之類的資料結構可以解決一些樹上修改的問題。還可以求lca,不過複雜度比rmq實現的lca多乙個log。下面是樹鏈剖分實現的lca 1 const int maxn 5e4 10 2 struct data edge maxn 1 5...

演算法入門 樹鏈剖分 輕重鏈剖分

目錄 3.0 求 lca 4.0 利用資料結構維護資訊 5.0 例題 參考資料 資料結構入門 線段樹 發表於 2019 11 28 20 39 dfkuaid 摘要 線段樹的基本 建樹 區間查詢 單點修改 及高階操作 區間修改 單點查詢 區間修改 區間查詢 標記下傳 標記永久化 閱讀全文 樹鏈剖分用...