動態樹初探 link cut tree

2021-05-23 05:43:36 字數 1159 閱讀 7120

很愚昧的以為動態樹是一種資料結構,現在才知道動態樹是是一類問題(dynamic tree problems)。

spoj上有一系列關於樹的很有趣的題目(qtree1~4),和樹鏈剖分、動態樹有關,所以就狠下心的研究了一番,多虧找到了一篇好**《qtree解法的一些研究 by yangzhe》,解決動態樹問題的資料結構叫link-cut tree(又是tarjan發明的,無限崇拜!!),看懂了思想以後便抱著視死如歸的心態編了起來(拿hnoi2010的bounce來練手),因為看了標程,7kb、8kb、7kb,=、=。

首先說說樹鏈剖分,差不多就是link-cut tree 的靜態版(靜態樹!?),前提是樹的形狀不發生改變。樹中的重邊的定義就是每個點向他最大的兒子(子樹大小最大)連的邊,其他的邊就是輕邊。可以證明乙個點到根節點經過的輕邊數不超過logn,證明:

定義size(i)為以i為根的子樹大小,

若 i 和 fa(i) 之間連的是輕邊

也就是 存在  j∈son(fa(i)),size(j)≥size(i)

又∵ size(fa(i))≥size(i)+size(j),

∴size(fa(i))>2*size(i).

每走一條輕邊節點數都會增大一倍,那當然不可能超過logn條輕邊咯。

對於一串連續的重邊,我們就把它壓縮為一條重路徑。

如果這棵樹的形狀不改變,那麼重路徑自然也不會發生變化,那我們可以用線段樹或者是虛二叉樹來維護,若會改變,則用splay tree維護(以深度為關鍵字)。

在實際link-cut tree的編寫中並不要考慮誰是重邊誰是輕邊,假設你訪問了某乙個點,就把它到父親的邊全改為重邊就可以了,可以證明也是logn的(證明有點懵。。)。

回顧hnoi2010的彈飛綿羊,這正是乙個動態樹問題(哎,我靠怎麼那時候不會捏?),要求支援這樣兩個操作:

1.詢問某個點的深度。

2.改變某個點的父親。

記得之前用塊狀鍊錶水過了,速度還不錯,不過看來 link-cut tree 還是以絕對優勢壓倒了:

塊狀鍊錶:

link-cut tree

這次還給了我乙個教訓,不要被標程嚇到了。。。可能牛們為了讓人更容易看懂才編長一點的吧,卻著實把我這種小白嚇到了。。。

自己編起來感覺也很舒服,74行,主要注意的還是旋轉時候的父親的轉化。

(裸的splay不解釋。。。都是想想寫寫胡編亂抽的)**:

動態SQL初探

1 普通sql 語句 select customerid,companyname,contactname,address city,phone from dbo.customers goexec select customerid,companyname,contactname,address ci...

動態規劃初探

最先聽說動態規劃還是在研究生的最優控制課上,課上介紹了用動態規劃解決最優問題。其實動態規劃 dynamic programming dp 和分治方法類似,都是通過組合子問題來求解原問題。不過動態規劃應用於問題重疊的情況,即不同的子問題具有公共的子子問題,每個子問題只求一次,而不必重新計算。就我個人的...

動態規劃初探

為了解決多階段決策問題,我們可以使用窮舉法和動態規劃方法。但是當決策和階段數量達到一定程度後,窮舉法帶來的龐大計算量極大的降低了我們解決該類問題的效率。為了避免窮舉法帶來的龐大計算量,於是我們引入了動態規劃方法去解決該類問題。首先,我們需要了解什麼是多階段決策問題。這不難理解,這裡我舉個簡單的例子來...