Link-Cut Tree
生活随笔
收集整理的這篇文章主要介紹了
Link-Cut Tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Link-Cut Tree
概述.
LCT是一種支持動態(tài)維護樹上路徑信息的數據結構,其本質是實鏈剖分,通過其他數據結構維護實鏈的信息達到維護路徑及一些子樹信息的效果(通常為splay)
剛開始學的時候感覺很難,但做過幾道題了解套路之后感覺還是一個很良心實用的東西QAQ。
實鏈剖分.
重鏈剖分把子樹大小作為標準,子樹結點個數最多的兒子作為重兒子。
長鏈剖分把子樹深度作為大小,子樹深度最大的兒子作為重兒子。
而實鏈剖分類似,但它的選擇方式是動態(tài)的,相當于動態(tài)地把某些邊設為實邊,其他為虛邊,并維護實鏈的信息,從而達到維護路徑信息的效果。
LCT的實現.
Access是LCT的核心操作,它的作用是把某一個結點到根的路徑設為實鏈,并將的兒子連向的邊設為虛邊,相當于制造了一個只包含根到的路徑的實鏈。
這一操作可以通過不斷splay來實現。
而實現了Access之后LCT的其他操作就能夠輕松地實現了(詳見下面的代碼)。
struct Link_Cut_Tree {int ch[MAXN][2],rev[MAXN],size[MAXN],s[MAXN],fa[MAXN],a[MAXN],stk[MAXN],sz=0;void Clear(int x) { rev[x]=ch[x][0]=ch[x][1]=fa[x]=a[x]=0; }void Update(int x) { if (!x) return; s[x]=a[x]^s[ch[x][0]]^s[ch[x][1]]; } void Rev(int x) { if (!x) return; rev[x]^=1; swap(ch[x][0],ch[x][1]); }void Pushdown(int x){ if (!rev[x]) return; Rev(ch[x][0]); Rev(ch[x][1]); rev[x]=0; }bool Isroot(int x) { return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x; }int Get(int x) { return ch[fa[x]][1]==x; }void Rotate(int x) {int father=fa[x],grandfa=fa[father],which=Get(x);if (!Isroot(father)) ch[grandfa][Get(father)]=x;fa[x]=grandfa;ch[father][which]=ch[x][which^1],fa[ch[father][which]]=father;ch[x][which^1]=father,fa[father]=x;Update(father),Update(x);}void Splay(int x) { int top=1; stk[top]=x;for (int p=x;!Isroot(p);p=fa[p]) stk[++top]=fa[p];while (top) Pushdown(stk[top--]);for (int father;father=fa[x],!Isroot(x);Rotate(x)) if (!Isroot(father)) Rotate(Get(x)==Get(father)?father:x);}void Access(int x) { for (int p=0;x;p=x,x=fa[x]) Splay(x),ch[x][1]=p,Update(x); }void Make_root(int x) { Access(x),Splay(x),Rev(x); };int Find_root(int x) { Access(x),Splay(x); while (ch[x][0]) Pushdown(x),x=ch[x][0]; Splay(x); return x; }void Split(int x,int y){ Make_root(x),Access(y),Splay(y); }void Link(int x,int y) { Make_root(x); if (Find_root(y)!=x) fa[x]=y; }void Cut(int x,int y) { Make_root(x); if (Find_root(y)!=x||fa[y]!=x||ch[y][0]) return; fa[y]=ch[x][1]=0,Update(x); }int Query_Xor(int x,int y) { Split(x,y); return s[y]; } } lct;LCT的應用.
目前只在某谷上做了一些比較容易的題,之后再補充吧。
維護動態(tài)連通性:
- P3690?【模板】Link Cut Tree (動態(tài)樹)
- P2147?[SDOI2008]洞穴勘測
動態(tài)維護生成樹:
- P4234?最小差值生成樹
- P2387?[NOI2014]魔法森林
類似LCT:
- P4338?[ZJOI2018]歷史
一點總結.
與其說LCT是一種數據結構,不如說LCT是一種維護樹上數據的思想(實鏈剖分),它的時間復雜度???比樹鏈剖分更加優(yōu)秀,并支持動態(tài)維護樹形結構,并且理解上不算困難,只要熟練掌握Splay就能輕松學會LCT了。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Link-Cut Tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 淘宝美工入门教程。
- 下一篇: [POJ2888] Magic Brac