**實現
和上次的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中.
這個時候我們要利用access
和splay
兩個操作. 先把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...