資料結構 LinkCutTree

2022-05-11 05:38:22 字數 3007 閱讀 7815

和重鏈剖分的概念有點點像。或者應該叫做實鏈剖分。

lct維護的「原樹」並非是一棵樹,而是一片森林。森林中的樹可以切成各種形狀的樹,也可以把不同的樹合併。lct內部的「輔助樹」也不是一棵樹,而是一片(更大的)splay森林。

原樹是一棵有根樹。支援以下操作:

1、對原樹節點x和節點y的鏈更新某資訊

2、對原樹節點x和節點y的鏈查詢某資訊

3、重新指定原樹的根節點

4、刪除原樹的邊x-y

5、新增原樹的邊x-y,其中y是深度更小的節點

lct維護一片splay森林,其中每一棵splay代表原樹的一條深度單調遞增/單調遞減的鏈(也就是說不拐彎的鏈)。每一棵splay的中序遍歷是原樹的鏈頂到鏈底。所以每個節點的實兒子是唯一的,父親也是唯一的。

實兒子:原樹中,當前節點的兒子,且當前節點處於同一棵splay中,當前節點知道它的實兒子是誰,實兒子也知道其父親是誰。

虛兒子:原樹中,當前節點的兒子,且當前節點不處於同一棵splay中,當前節點並不知道它的虛兒子有哪些,但是虛兒子知道其父親是誰。

struct linkcuttree 

}inline void pushup(int x)

if(t = ch[x][1])

}inline void pushdown(int x)

if(t = ch[x][1])

mul[x] = 1;

}if(add[x])

if(t = ch[x][1])

add[x] = 0;

}if(rev[x])

if(t = ch[x][1])

rev[x] = 0;}}

inline bool which(int x)

inline bool notroot(int x)

void rotate(int x)

void pushdownall(int x)

int splay(int x)

rotate(x);

}return x;

}int access(int x)

return y;

}int makeroot(int x)

int findroot(int x)

splay(x);

return x;

}int select(int x, int y)

void cut(int x, int y)

bool cut2(int x, int y)

}return false;

}void link(int x, int y)

bool link2(int x, int y)

return false;

}void mul(int x, int y, int v)

void add(int x, int y, int v)

ll sum(int x, int y)

} lct;

access:把x到原樹的根節點的路徑變為實路徑。

額外提供乙個返回值,表示最後一次虛邊變實邊時,虛邊父親的編號。連續兩次access操作時,第二次access操作的返回值就是這兩個節點的lca。返回值表示x到根節點所在的鏈代表的splay的樹根,這個節點已經被旋轉到splay的根,並且其父親一定為空。

makeroot:指定原樹的根節點為x(換根)

findroot:找x在輔助樹的樹根,也就是x在原樹的實鏈的鏈頂

select:把x和y之間的路徑切成乙個splay,根是y。(想要根是誰,最後就splay一下誰就行)

cut:切斷x和y的邊

cut2:假如x和y之間有邊,則切斷x和y的邊

link:連線x和y的邊

link2:假如x和y之間不連通,則連線x和y的邊

update:更新點x的權值為v

struct linkcuttree 

}inline void pushup(int x)

if(t = ch[x][1])

}inline void pushdown(int x)

if(t = ch[x][1])

mul[x] = 1;

}if(add[x])

if(t = ch[x][1])

add[x] = 0;

}if(rev[x])

if(t = ch[x][1])

rev[x] = 0;}}

inline bool which(int x)

inline bool notroot(int x)

void rotate(int x)

void pushdownall(int x)

int splay(int x)

rotate(x);

}return x;

}int access(int x)

return y;

}int makeroot(int x)

int findroot(int x)

splay(x);

return x;

}int select(int x, int y)

void cut(int x, int y)

bool cut2(int x, int y)

}return false;

}void link(int x, int y)

bool link2(int x, int y)

return false;

}void mul(int x, int y, int v)

void add(int x, int y, int v)

ll sum(int x, int y)

} lct;

由於lct中根是會變的,所以不能直接把資訊存在點上,要對每條邊進行拆邊。

需要額外統計虛兒子的貢獻,由於在splay中看不到原樹的虛兒子,所以lct對此的維護比較麻煩。

並且要求具備逆元,可以說lct並不擅長維護子樹的資訊。

資料結構 資料結構緒論

資料結構是相互間存在一種或多種特定關係的資料元素的集合。程式設計 資料結構 演算法 資料結構是一門研究非數值計算的程式設計問題中的操作物件,以及他們之間的關係和操作等相關問題的學科。資料元素是組成資料的 有一定意義的基本單位,是計算機中通常作為整體處理,也被稱為記錄。乙個資料元素可以由若干個資料項組...

資料結構 資料結構演算法

分治法 對於乙個規模為n的問題,若該問題可以容易地解決 比如說規模n較小 則直接解決 否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞迴地解這些子問題,然後將各子問題的解合併得到原問題的解。動態規劃法 這種演算法也用到了分治思想,它的做法是將問題例項分解為更小的 相似的子...

資料結構 01 資料與資料結構

1.資料data 資料是描述客觀事物的符號,是計算機中可以操作的物件,是能被計算機識別,並輸入給計算機處理的符號集合。2.資料元素data elements 資料元素是組成資料的 有一定意義的基本單位,在計算機中通常作為整體進行處理。3.資料物件data object 資料物件是性質相同的資料元素的...