**:blog.csdn.net/wu_tongtong/article/details/78654635
lct基礎知識回顧)
為了方便說話先說一下下面可能出現的名詞的意思(。其實大家可以先跳過這一段,如果後面沒看懂我在寫什麼再回來看這裡)
我們要用lct維護一棵樹,那麼這棵樹會有乙個原樹結構,以及乙個當前在lct裡的結構,我們知道我們用lct維護了乙個原樹的鏈剖分,凡是被剖分到同一條鏈裡的點用乙個splay以深度為關鍵字維護,而不同的鏈之間用虛邊相連,虛邊為只有兒子指向爹,爹不指向兒子
那麼我們可以定義乙個點x在lct結構中的兒子,為有虛邊指向x的點或者在splay中是x的兒子的點,例如上圖中,4在lct結構中的兒子有7和2,並且由此我們可以定義出lct結構裡的子樹,上圖中4的子樹包含4,7,2,6,8,5
由於虛實邊的存在,我們可以把兒子分為實兒子和虛兒子,實兒子為splay中的兒子,虛兒子為有虛邊指向他的兒子,我們還可以把子樹劃分為實子樹、虛子樹和自己三部分,實兒子的子樹為實子樹,虛兒子的子樹為虛子樹(實兒子的虛子樹也算實子樹的一部分)
例如上圖中,4的實兒子有2,虛兒子有7,實子樹包含2,5,6,8,虛子樹包含7
子樹資訊
我們先來考慮維護子樹的資訊和
對於乙個點x,如果我們對x進行access操作,那麼他的虛子樹內將包含且僅包含他原樹中子樹內除了他自己以外的所有點,這時如果我們維護了他的虛子樹資訊和,我們把這個資訊與他自己的資訊合併,我們就得到了他在原樹中的子樹資訊
在下面的討論中,我們發現我們可以同時維護乙個點的虛子樹資訊和lct子樹資訊來達到維護虛子樹資訊的目的
考慮乙個點的虛子樹資訊會在什麼情況下發生改變,乙個點的虛子樹資訊改變,當且僅當進行link或者access操作時。
在進行access操作時,我們會有更換乙個點的x右兒子的操作,這時我們要把x原來的右兒子的lct子樹資訊加入x的虛子樹資訊,把x的新的右兒子的lct子樹資訊從x的虛子樹資訊中減去
在進行link操作時,我們會先把點x換根,然後連一條x到y的虛邊,這時我們發現不僅y的虛子樹資訊需要加入x的lct子樹資訊,y的所有祖先的lct子樹資訊也需要更改,而這樣我們就沒法維護了,所以在進行link操作的時候我們需要把y也換根(其實access再splay就行了,不用換成根),這樣就只會對y的虛子樹資訊和lct子樹資訊產生影響
我們還需要維護乙個x的lct子樹的資訊和,x的lct子樹的資訊和就等於x的實兒子的lct子樹資訊和加上x的虛子樹的資訊和加上x自己,在splay的update函式中就可以直接維護
這樣我們就完成了對子樹資訊的維護
換根操作、cut操作和鏈修改操作並不影響我們上邊的討論,所以也是茲磁的
**可參照bzoj4530 [bjoi2014]
邊權資訊
這個邊權資訊的維護方法是從vfk的部落格裡學的,不過他那篇文章本來是講動態仙人掌的-_-lct並不是重點
對於每個點,我們定義他的「前一條邊」和「後一條邊」,前一條邊指的即是他在原樹中與父親之間的邊(可能不存在),而後一條邊指的是在當前的鏈剖分下,與他在同一條剖分鏈上的兒子與他之間的邊(可能不存在)
例如上圖中,1的前一條邊與4的後一條邊都是不存在的,而2的前一條邊就是(1,2),後一條邊是(2,4),5的前一條邊就是(2,5)
我們考慮對於每個點,維護他的前一條邊和後一條邊是哪條,注意是維護是哪條邊,而不是直接維護邊權
考慮在什麼情況下前一條邊和後一條邊會發生變化,首先在進行翻轉操作時,我們顯然除了交換左右兒子還要交換前一條邊和後一條邊,在link操作時,我們要把x的前一條邊設成(x,y),在cut時,我們要把cut掉的兩個點其中乙個的前一條邊設成沒有,另乙個的後一條邊設成沒有
另外在access操作時,我們有更換x的右兒子的操作,即改變了當前的鏈剖分,所以x的後一條邊理應變成他新的右兒子所在的splay裡最左邊的點的前一條邊,而為了找到這一條邊,我們還需要維護每個splay的第一條邊和最後一條邊,即最左邊的點的前一條邊和最右邊的點的後一條邊,為什麼要維護最後一條邊呢,因為在翻轉的時候我們要交換這兩個值
這樣的話,我們對每個點維護他的splay子樹所代表的鏈的邊權資訊和,注意乙個splay所代表的鏈所包含的邊只有那些兩個端點都在這個splay裡的邊,比如上圖中2的前一條邊是(2,1)並且2在4的splay子樹裡,但是4的splay子樹所代表的鏈是不包含(2,1)的
那麼我們考慮這個資訊的合併,如果乙個點有左子樹,那麼他的前一條邊的另乙個端點一定在左子樹里,所以他的鏈資訊和就要加上左子樹的鏈資訊和以及他的前一條邊的資訊,右子樹亦然
我們考慮鏈修改操作,與鏈資訊合併類似,如果他有左兒子,那麼更改他的前一條邊的權值,右兒子亦然,然後對這個點打標
然後就完成了邊權的維護
**可參照uoj#207 共價大爺遊長沙
首先我們要明確一棵lct到底是怎麼維護資訊的:
這裡寫描述
我們可以發現,我們在expose乙個結點之後(如圖,假如我們expose的是4)
該點的所有虛邊所連的點集就是該點的在原樹上的子樹(除該點本身的資訊)
所以我們是可以利用這乙個性質的
子樹資訊:
對於乙個點x,如果我們對x進行expose操作
那麼ta的虛子樹內將包含且僅包含 ta原樹中子樹內除了ta自己以外的所有點
如果我們維護了ta的虛子樹資訊和,我們把這個資訊與ta自己的資訊合併,我們就得到了ta在原樹中的子樹資訊
在下面的討論中,我們發現我們可以同時維護乙個點的虛子樹資訊和lct子樹資訊來達到維護虛子樹資訊的目的
我們需要維護乙個x的lct子樹的資訊和
x的lct子樹的資訊和就等於x的實兒子的lct子樹資訊和加上x的虛子樹的資訊和加上x自己,
在splay的update函式中就可以直接維護
考慮乙個點的虛子樹資訊會在什麼情況下發生改變:
乙個點的虛子樹資訊改變,當且僅當進行link或者expose操作時
在進行expose操作時,
我們會有更換乙個點x的右兒子的操作,
這時我們要把x原來的右兒子的lct子樹資訊加入x的虛子樹資訊,
把x的新的右兒子的lct子樹資訊從x的虛子樹資訊中減去
(一定細細體會這句話蘊含的真理)
在進行link操作時,
我們會先把點x換到根上,然後連一條x到y的虛邊,
這時我們發現不僅y的虛子樹資訊需要加入x的lct子樹資訊,y的所有祖先的lct子樹資訊也需要更改,
所以在進行link操作的時候我們需要makeroot(x)再makeroot(y),
我們把x的爸爸設成y,這樣只要把x的lct子樹資訊統計入y得虛子樹資訊中即可
(不要忘了update(y))
換根操作、cut操作和鏈修改操作並不影響我們上邊的討論
例題:bzoj4530:題解
邊權資訊
對於每個點,我們定義他的「前一條邊」和「後一條邊」,
前一條邊指的即是ta在原樹中與父親之間的邊(可能不存在),而後一條邊指的是在當前的鏈剖分下,與ta在同一條剖分鏈上的兒子與他之間的邊(可能不存在)
例如上圖中,1的前一條邊與4的後一條邊都是不存在的,而2的前一條邊就是(1,2),後一條邊是(2,4),5的前一條邊就是(2,5)
對於每個點,維護ta的前一條邊和後一條邊是哪條,注意是維護是哪條邊,而不是直接維護邊權
考慮在什麼情況下前一條邊和後一條邊會發生變化:
在翻轉操作時,我們顯然除了交換左右兒子還要交換前一條邊和後一條邊
在link操作時,我們要把x的前一條邊設成(x,y)
在cut操作時,我們要把cut掉的兩個點其中乙個的前一條邊設成「不存在」,另乙個的後一條邊設成「不存在」
在access操作時,我們有更換x的右兒子的操作,即改變了當前的鏈剖分,
所以x的後一條邊理應變成他新的右兒子所在的splay裡最左邊的點的前一條邊,
而為了找到這一條邊,我們還需要維護每個splay的第一條邊和最後一條邊,
即最左邊的點的前一條邊和最右邊的點的後一條邊,
為什麼要維護最後一條邊呢,因為在翻轉的時候我們要交換這兩個值
這樣的話,我們對每個點維護他的splay子樹所代表的鏈的邊權資訊和,
注意乙個splay所代表的鏈所包含的邊只有那些兩個端點都在這個splay裡的邊,
比如上圖中2的前一條邊是(2,1)並且2在4的splay子樹裡,但是4的splay子樹所代表的鏈是不包含(2,1)的
考慮資訊的合併:
如果乙個點有左子樹,那麼他的前一條邊的另乙個端點一定在左子樹里,
所以他的鏈資訊和就要加上左子樹的鏈資訊和以及他的前一條邊的資訊,右子樹亦然
我們考慮鏈修改操作:
與鏈資訊合併類似,如果他有左兒子,那麼更改他的前一條邊的權值,右兒子亦然,然後對這個點打標
這樣就完成了邊權的維護
NOI2014 魔法森林 LCT維護MST
bzoj3669 題面 從更簡單的情況入手,如果邊權只有 a 沒有 b應該怎麼處理?這時候問題就是找一條從1到n的路徑,使得最長的邊盡量短。根據最小生成樹的性質,這樣的邊一定在最小生成樹上。如果a 固定,得到的解法是一樣的。那麼可以分別討論每乙個 a,對於權值不大於 a 的邊對 b做一次最小生成樹。...
LCT 維護邊雙 點雙的模板
用 text 維護邊雙的做法是 加入一條非樹邊時,將這段樹上路徑合併為乙個點代表這個邊雙,具體實現用並查集合並點,在 text 與 text 的過程中對輔助樹上父親做路徑壓縮。用 text 維護點雙的做法是 加入一條非樹邊時,將這段樹上路徑全部砍斷,新建乙個點代表這個點雙,將原來那些點向新點連虛邊。...
bzoj 4530 大融合(LCT維護子樹資訊)
傳送門biu 用lct維護子樹資訊。lct維護子樹資訊 子樹資訊lct lct維護邊權 邊權lct 知識點講解 xsiz代表節點的虛兒子的size和。rsiz代表該點在splay中的size加上該點的xsiz。每次maintain操作可以更新節點的rsiz值。增加乙個update函式來實現實兒子到虛...