自己定的學習計畫看起來完不成了(兩天沒學東西,全在補題),決定趕快學點東西
於是就學lct了
link/cut tree是一種資料結構,我們用它解決動態樹問題
但是lct不叫動態樹,動態樹是指一類問題(那麼lct的中文名是啥啊)
這是⼀個和 splay ⼀樣只需要寫幾 (yi) 個 (dui) 核心函式就能實現一切的資料結構
維護乙個森林,支援刪除某條邊,加入某條邊,並保證加邊,刪邊之後仍是森林。我們要維護這個森林的資訊。
一般操作有兩點連通性,兩點路徑權值和,連線兩點和切斷某條邊、修改資訊等。
普通的樹剖以子樹大小作為劃分條件
然而動態樹問題需要什麼樣的剖分呢?
我們把每條實鏈建乙個splay來維護整個鏈區間上的資訊
輔助樹example:
現在有一棵樹,其中粗邊為實邊,虛線邊為虛邊
那麼輔助樹的結構如下
原樹和輔助樹的結構關係
變數宣告
函式宣告
⼀般資料結構函式 (字面意思)
pushup(x)
pushdown(x)
splay 系函式
get(x)
獲取 x 是父親的哪個⼉子。
splay(x)
通過和 rotate 操作聯動實現把 x 旋轉到 當前 splay 的根。
rotate(x)
將 x 向上旋轉一層的操作。
新操作isroot(x)
判斷當前節點是否是所在 splay 的根
access(x)
把從根到當前節點的所有點放在⼀條實鏈裡, 使根到它成為一條實路徑, 並且在同一棵 splay 裡裡。
update(x)
在 access 操作之後, 遞迴的從上到下pushdown
更新資訊。
makeroot(x)
使 x 點成為整個輔助樹的根。
link(x, y)
在 x, y 兩點間連⼀一條邊。
cut(x, y)
把 x, y 兩點間邊刪掉。
find(x)
找到 x 所在的 splay 的根節點編號。
fix(x, v)
修改 x 的點權為 v。
split(x, y)
提取出來 x, y 間的路路徑, 方便便做區間操作
巨集定義函式講解
pushup
inline void pushup(int p)
pushdowninline void pushdown(int p)
if(tag2[p]!=std_tag_2)
//...
}
rotate & splay#define get(x) (ch[f[x]][1]==x)
inline void rotate(int x)
inline void splay(int x)
}
上面的還是splay用的函式,看不懂請自學splay
下面要開始lct獨有的函式啦
isroot
//如果乙個兒子既不是父親的左兒子,也不是右兒子,那麼他就是根
//原因:我們說過如果乙個兒子不是實兒子,那麼父親的ch裡找不到他
#define isroot(x) (ch[f[x]][0]!=x && ch[f[x]][1]!=x)
access//lct的核心操作
inline void aceess(int x)
}
我們有這樣一棵樹,實線為實邊,虛線為虛邊
//回顧**
inline void access(int x)
}
我們發現access其實很容易。只有如下四步操作:
把當前節點轉到根。
把當前節點的右兒子換成之前的節點。
更新當前點的資訊。
把當前點換成當前點的父親, 繼續操作。
update
//從上到下一層層pushdown即可
void update(int p)
makerootinline void makeroot(int p)
link
link 兩個點其實很簡單, 先 make_root(x) , 然後把 x 的父親指向 y 即可。顯然, 這個操作肯定不能發生在同一棵樹內。記得先判一下。
inline void link(int x,int p)
split
cut
inline void cut(int x,int p)
find
inline int find(int p)
LCT 學習筆記
可能叫動態鏈剖分會比較合適?回顧重鏈剖分,我們將 x 所有兒子中子樹 siz 最大的那個兒子欽定為重兒子,乙個結點與它的重兒子的連邊稱為重邊,其餘稱為輕邊。重邊和輕邊形成的鏈把整棵樹剖分成了若干個 dfs 序上的連續段,這樣我們就能使用諸如線段樹等靜態資料結構維護鏈上的資訊了。重剖的侷限性在於它所維...
動態樹(LCT)學習筆記
candy flashhu xzyxzy 想要學lct的還是看這幾篇比較好。我這篇只是總結一些容易理解錯的或者一不小心打錯的地方。lct link cut tree 就是又可以link 動態加邊 又可以cut 動態刪邊 的維護一片森林的資料結構。lct使用實鏈剖分,對每一條實鏈用splay維護 一棵...
LCT入門筆記
lct是動態樹的一種,通過維護實鏈和虛鏈來維護所有路徑之間的關係 類似於樹鏈剖分 這樣做的目的是為了減少某些鏈上的修改 查詢等操作的複雜度。雖然lct常數巨大。學lct的大部分都會樹剖吧?我們都知道樹剖維護子樹最大的兒子並形成一條重鏈,由於樹剖是靜態的,所以可以用線段樹來維護。而由於lct需要維護動...