動態樹分治

2021-07-24 02:48:25 字數 825 閱讀 7529

不得不說,樹結構真是巧妙神奇。因為結構簡單,所以變形剖多,在競賽中玩出的花樣也最多。

動態樹分治,顧名思義,解決待修改的樹分治問題。原本的樹分治基於邊或者重心的分治可以解決大多數靜態樹鏈問題,但是待修改怎麼辦?其實很簡單,因為樹結構是不變的,就是樹分治的基礎結構不變,對於修改和詢問,只需要在第一次樹分治的基礎上用一些資料結構維護一些資訊即可。

話雖這麼說,但是實際上動態樹分治是在樹分治的基礎上重新建了一顆新樹,被叫做重心樹。理解動態樹分治需要先理解樹分治的過程。樹分治本身基於重心的劃分,每次找到樹重心,然後刪除重心,樹將變成若干棵子樹,對於每顆子樹重複這個過程。因為重心的性質,這個過程最多遞迴層數是log級別的,重心樹也由此而來。

重心樹的定義是,將樹分治看做log層劃分,上文說到樹分治的重心劃分最多log層,每層對應一些子樹的重心,將第一次劃分的重心即 原樹的重心當做重心樹的根,下一層子樹的重心當成自己的孩子,依次做log次便建立了一顆樹,稱為重心樹。根據樹分治的性質,在重心劃分過程中,我們列舉到了每個節點作為重心的情況,也就是說原樹的每個節點都在重心樹中。

重心樹有很多很好的性質,比如深度最大為log級別,最長路徑長度為log級別。

為了解決問題,我們需要用重心樹維護一些東西。這些東西就是指重心所在子樹的所有節點的資訊。因為樹分治有log層劃分,每次劃分最多n個點,所以需要維護的資訊最多為nlogn個。其次,劃分log層,每個節點最多屬於log個重心,也就是說,每個點資訊的更新只需對log個重心的資訊進行更新。即更新複雜度為log級別。詢問也是同樣道理。

以上就是我對動態樹分治的理解,不正確的地方希望大家指正。

除了動態點分治,還有動態邊分治。道理是類似的,只是邊分治的好處是對應的重心樹是二叉樹,處理更方便。

模板 動態 DP 動態樹分治

題面鏈結 include define ll long long define rg register using namespace std templateinline void read t x templateinline void write t x if x 0 x x,putchar ...

COGS 2278 樹黑白(動態樹分治)

傳送門 cogs 2278 題意 給定一棵樹,要求維護以下操作 1 m u 將u節點反色 2 q u 查詢u到所有黑色節點距離和 題解 動態樹分治,更新時判斷一下原本是黑色還是白色,是黑色就減去u與根的距離,是白色就加上 includeusing namespace std const int mx...

動態逆序對(CQOI)(CDQ分治 or 主席樹)

先寫乙個cdq分治的寫法吧,主席樹。希望我以後會補。題意 先給定乙個1 11 n nn的全排列,然後有m mm次刪除操作,求每次刪除操作之前逆序對的個數。思路 題目說求刪除操作之前逆序對的個數,反過來不就是每次插入操作之後逆序對的個數嗎?然後如果能求出每次插入操作所增加的逆序對個數,再利用字首和不就...