關於 Link Cut Tree 的一些說明

2021-08-23 12:34:30 字數 4186 閱讀 3753

**實現

和上次的splay一樣,把你們的independence開起來,今天我們再嗨一次!

學習link cut tree需要一定的splay的基礎,如果你的基礎還是像我一樣不夠紮實,上面的鏈結,學習一下sp

lay spl

ay

再走.

這個部落格真是命運多舛.寫完了突然卡了發布不了,然後重新整理一下又變回原來這樣子了.

想必大家都知道lct指的是動態樹了.

首先它到底是維護什麼東西的呢?

大家肯定是學過樹鏈剖分的.

樹鏈剖分是將樹按照重兒子剖成一條一條的鏈,也被稱為重鏈剖分.

而lct是實鏈剖分.

所謂實鏈剖分,是對於每乙個節點將它和它某乙個兒子的邊划為實邊,和其他兒子的邊都劃為虛邊.

而虛實邊是在不斷地變化之中的,因此不能使用線段樹來維護,而應該使用splay.

lct維護的物件是乙個森林,借助實鏈剖分,它可以支援的操作多到無法想象.

它有幾條性質:

1.每乙個splay是維護一條鏈,鏈上不能有兩個深度相同的點,並且中序遍歷每一棵splay得到的點在原樹中的深度是嚴格遞增的.

2.每乙個節點僅僅包含於一棵splay中.

3.實邊包含在splay中,虛邊從一棵splay指向另乙個節點(該splay中中序遍歷最靠前的節點在原樹中的父親.)

注意被虛邊指向的點不能沿著虛邊訪問回去,即認父不認子.

link cut tree 中最重要的乙個操作,是打通某節點到根的路徑,也即將該節點與根放進同一棵splay.

明顯此時在原樹中從根節點到該節點的邊全部變為實邊,與路徑上的點無關的其它點之間的邊相對變為虛邊.

那麼操作順序是這樣的.

1.設當前被操作點為x,則先把x splay到當前splay的根.

2.把x的右兒子設為y.

3.更新x的資訊.

4.讓y=x,將x變為x虛邊指向的父親.

所以**如下.只需要乙個for迴圈.

void access(int x)
僅僅是將根和某個點之間的路徑拉出來並沒有什麼用處.現在我們需要兩個節點之間的路徑的資訊.,

然而發生路徑不能滿足按照深度嚴格遞增的情況,由於性質1,這樣的路徑不能產生在乙個splay中.

這個時候我們要利用accesssplay兩個操作. 先把x

x

access一下,然後splay到根.

這個時候思考一下人生.

此時的x

' role="presentation" style="position: relative;">x

x是splay裡面深度最大的點,沒有右子樹.我們只要把整棵樹顛倒過來,就可以使

x x

沒有左子樹,從而變成深度最小的點,也就是根.

int rev(int x)

void mkrt(int x)

可以找到

x' role="presentation" style="position: relative;">x

x所代表原樹的樹根,用來判斷兩點間的連通性. 先把x

x

access一下,再splay到根,不斷地找它的左兒子,就會找到深度最小的節點,也就是根.

void push_down(int x)

int fdrt(int x)

現在我們可以make_root,我們可以利用上面的工具直接訪問x,

y' role="presentation" style="position: relative;">x,y

x,y兩點在樹上的路徑.

void split(int x,int y)

//此時直接調取y的資訊就可以了.

連一條x→

y x→y

的邊. 把x

x

變成ro

ot' role="presentation" style="position: relative;">roo

troo

t之後,判斷

y y

和x' role="presentation" style="position: relative;">x

x是否已經連線.

如果find_root(y)=x說明x,

y x,y

已經連線,直接返回.

int link(int x,int y)
斷開x,

y x,y

之間的邊.

如何判斷x,

y x,y

之間是否已經連邊?

首先它們必須要直接或者間接連通.

所以find(y)=x. 如果y

y

與x' role="presentation" style="position: relative;">x

x沒有直接的父子關係,必然能找到一些點,它的中序遍歷在x,

y x,y

之間.

所以fa[x]=y.

然而即使

y y

是x' role="presentation" style="position: relative;">x

x的父親,

x x

也不能有右子樹.

x' role="presentation" style="position: relative;">x

x若存在右子樹,它右子樹中的點的中序遍歷也是在x,

y x,y

之間的.

所以rs(x)=0.

接下來將fa[x]ls(y)清空.顯然

x x

一定是y' role="presentation" style="position: relative;">y

y的左兒子.

int cut(int x,int y)
洛谷 p3690 模板 動態樹

#include//ithea myse valgulious

namespace chtholly

template

inline

bool read(mitsuha &x)

template

inline

int write(mitsuha x)

inline

char fuhao()

}using

namespace chtholly;

using

namespace

std;

const

int yuzu=3e5;

typedef

int fuko[yuzu|10];

int n,m;

struct link_cut_tree// not_root

int rev(int x)

void push_down(int x)

void push_up(int x)

void zhuan(int x)

void pushall(int x)

int splay(int x)push_up(x);

}int access(int x)

void mkrt(int x)

void split(int x,int y)

int fdrt(int x)

int link(int x,int y)

int cut(int x,int y)

}my_;

#define split my_.split

#define link my_.link

#define cut my_.cut

#define val my_.val

#define splay my_.splay

#define sum my_.sum

int main()

}}

謝謝大家.

關於Integer int String的一些方法

關於integer int string的一些方法 1.integer的parseint 和 valueof。integer靜態記憶體儲存 128 127 1 返回型別 parseint 返回的是int。valueof 返回的是integer 2 判斷相等 int 用 integer 用 equal...

關於Android Broadcast 的一樁血案

之前一直使用broadcast都僅僅侷限於簡單呼叫,疑惑是根據需求選擇傳送方式,亦或是看心情決定是什麼方式註冊,直到今天,發生了乙個關於廣播的血案,事情的經過是這樣 嫌疑人 傳送了乙個無序廣播,通知各位聽眾某某事情,聽眾 舉報別人聽到了,它沒聽見,大喊冤枉,我都廣播了,並且是不分高低貴賤的無序廣播,...

mysql關於日期 關於mysql日期的一些例子

mysql中的月份計算 減少乙個月,比如 原來的subtime 2006 10 22 12 22 22 減少後變成 2006 9 22 12 22 22 update message set subtime date sub subtime,interval 1 month 增加乙個月 update...