1. 程式人生 > >動態樹之Link-Cut Trees

動態樹之Link-Cut Trees

關於動態樹

動態樹(Dynamic Trees)問題, 即要求我們維護一個由若干棵子結點無序的有根樹組成的森林。 要求這個資料結構支援對樹的分割,合併,對某個點到它的根的路徑的某些操作, 以及對某個點的子樹進行的某些操作。(來源——QTREE解法的一些研究byYangZhe)

解決動態樹問題有很多種方法 ,這裡介紹Link-Cut Trees,它不能夠實現“對某個點的子樹進行的某些操作”,但是對於大部分動態樹問題來說還是夠用了(其他動態樹好像比較冷門)。

動態樹的主體思想和樹鏈剖分很相似(樹鏈剖分戳這裡),非常頻繁地運用到了Splay TreeSplay模板戳這裡

無關內容:
還有一種動態樹叫做Euler-Tour Trees,能夠實現對子樹的某些操作,然而我並沒有找到有任何關於它的中文文獻。。。
所以等到我哪天英文達到了那個水平再去學吧。。。。

介紹

Link-Cut Trees是由SleatorTarjan發明的,這裡膜拜一下Tarjan(Orz),LCT,LCA,LCP的發明者中都有他的名字。。。(還有很多很多演算法。。。)

定義一些神奇的稱呼:

  • access(x):訪問節點x
  • PreferredChild:如果結點v的子樹中, 最後被訪問的結點在子樹w中, 這裡wv的兒子, 那麼就稱wvPreferredChild
  • PreferredEdge:每個點到它的PreferredChild的邊稱作PreferredEdge
  • PreferredPath:由Preferr
    edEdge
    連線成的不可再延伸的路徑稱為 PreferredPath

其中access(x)Link-Cut Trees最基本的操作,沒有之一。就像Splay操作對於Splay Tree一樣。

容易得出整棵樹就被劃分成了若干條 PreferredPath。對每條 PreferredPath, 用這條路上的點的深度作為關鍵字, 用一棵平衡樹來維護它(一般使用Splay,理論上Treap也可以,可是我從沒有看見有人這樣做過)。然後這棵平衡樹就被叫做AuxiliaryTree。我們把AuciliaryTree中深度最小的節點的父親節點稱為PathParent

Link-Cut Trees

就是將要維護的森林中的每棵樹 T 表示為若干個 AuxiliaryTree, 並通過PathParent將這些AuxiliaryTree連線起來的資料結構

access(x)操作

一旦我們呼叫access(x),那麼從點x到根結點的路徑就成為一條新的 Pr<