Link Cut Tree學習小記

2021-08-01 09:26:14 字數 1975 閱讀 5873

lct幾個月前就學了,花了我一整天問alan_cty才搞會

lct的左右就是維護樹上的一些值,和樹鏈剖分有相同的作用,也有超過樹鏈剖分的作用

lct也就是動態樹,意思就是樹是會動的,也就是有連邊和刪邊兩個操作

和鏈剖一樣,邊可以分為兩種,重邊(偏愛邊)和輕邊。一條重邊連起來的是一條鏈,在同一棵splay中(也就是說有好多棵splay)

這樣就會有兩種樹,我稱之為原樹和splay

splay中左子樹都比當前點在原樹中淺,右子樹則都比當前點在原樹中深

定義:

fa[x]表示x在splay中的父親,沒有就是0

p[x]為x在原樹中的輕邊父親(path parent),若沒有或原樹中x與它父親的邊為重邊則為0

root為原樹的根

如在上左圖中,p[d]=b,而p[e]=0

access(x)表示將x到root之間的所有邊變成重邊,也就是把這些點放到同一棵splay中

注意一點,如上圖中access(n)之後,原來a和b是重邊,變成了輕邊,這是因為乙個點與所有兒子中只能有一條重邊

code

t[x][0/1]為splay中x的左/右子樹

void access(int x)

}

splay(x,y)就是在splay中將x旋轉到y的下面

結合**和再畫一下圖,應該可以理解

這個操作是lct的核心

這個理解了,就相當於理解了lct

注意:splay中的rotate操作在lct中略微有點不同,因為有p這個陣列,所以rotate在旋轉的時候也要考慮到p

code

bool lr(int x)

void rotate(int x)

void splay(int x,int y)

}

makeroot(x)表示把x變成原樹的root

**:

void makeroot(int x)

rev為翻轉標記

access(x)之後,x所在的splay中就有且只有x到root上的所有點,此時x在最深處

將splay旋轉之後x就變成了最淺的點,也就是root

當splay被破壞或者被修改時,這個翻轉會以p傳到原樹中,所以是正確的

這個是lct操作中很重要的乙個

接下來的操作就是用來玩的了

**

void link(int x,int y)

很好理解吧?將x和y連邊(保證原來沒邊,連之後不形成環)

把x變成原樹的根,將x的輕邊父親變成y

**

void cut(int x,int y)

這個高階一點

切掉x和y之間的連邊(保證原來有邊)

在makeroot和access後,splay就只有x和y兩個點,斷掉之間的邊,維護好fa和p即可

當要修改或查詢原樹中x到y路徑上的點時:

makeroot(x);access(y);splay(x,0);
這樣之後,splay中x就代表了x到y路徑

因為維護的資料都在點上,所以維護邊的值時,要多開乙個點,代表邊的值,並與原來邊相連的兩個點連邊,之後與上面點的修改查詢一樣

最簡單的:

洛谷和bzoj中有 [hnoi2010]bounce 彈飛綿羊

就只用link,cut,查詢樹的大小

我的詳細題解這裡

稍複雜的:

很多oj都有 【noi2014】魔法森林

我的詳細題解這裡

更難一點的:

【gdsoi2017】中學生資料結構題

我的詳細題解這裡

有大神找到錯誤的歡迎補充和打臉

Link Cut Tree學習小記

link cut tree簡稱lct,是維護動態樹方式的一種,是乙個可以對樹進行新增鏈或子樹,刪除鏈或子樹等等,可以支援對樹的結構進行修改的演算法。樹鏈剖分只能維護靜態樹,就是只能對樹上的點的值進行修改的演算法,一般還是用線段樹來維護的。所以lct就厲害了,首先是維護方式不同,其次它是用splay來...

Link Cut Tree學習總結

title link cut tree學習總結 categories 演算法 date 2016 1 14 21 30 00 tags lct,演算法 lct是一種用於解決動態樹問題的資料結構。大體上的感受,lct就是樹鏈剖分和splay的結合版,什麼意思呢?因為要動態維護樹的結構和樹上的資訊,所以...

Link Cut Tree 學習筆記

link cut tree,用來解決動態樹問題。巨集觀上,lct維護的是森林而非樹。因此存在多顆lct。有點像動態的樹剖 鏈的確定通過 access 操作 每條鏈用一顆 splay 維護。splay 維護鏈的關鍵字是深度,因此一條鏈的頂端就是 splay 中鍵值最小的點 由於lct的資料有很多,在此...