Link Cut Tree学习笔记
捋一下思路
模板題:https://www.luogu.org/problemnew/show/P3690
推薦LCT的教程,個(gè)人認(rèn)為很詳細(xì),本文做了部分引用:https://www.luogu.org/blog/flashblog/solution-p3690
前置知識(shí):Splay
LCT是一種動(dòng)態(tài)樹(shù),支持連邊和斷邊,還有樹(shù)上路徑的查詢
LCT似乎是用Splay維護(hù)深度,這點(diǎn)知道了會(huì)感覺(jué)好理解一些
重要的操作有:
access(x),將x到根節(jié)點(diǎn)的路徑上的邊都變成重邊。循環(huán)處理,只有四步——轉(zhuǎn)到根;換兒子;更新信息;當(dāng)前操作點(diǎn)切換為輕邊所指的父親,轉(zhuǎn)第一步
makeroot(x),將x變?yōu)樗赟play的根節(jié)點(diǎn)。access操作后x變成Splay內(nèi)深度最大的點(diǎn),然后像Splay一樣把x轉(zhuǎn)上去
findroot(x),找所在樹(shù)的原根。不停找左兒子,因?yàn)樽髢鹤泳S護(hù)的深度比當(dāng)前節(jié)點(diǎn)小。
split操作。把一個(gè)點(diǎn)轉(zhuǎn)到根節(jié)點(diǎn),原路徑就是另一個(gè)點(diǎn)到根節(jié)點(diǎn)的路徑。然后把下面的點(diǎn)轉(zhuǎn)上去更新答案。
link(x, y),使x的父親指向y,連一條輕邊。如果在同一棵樹(shù)則不連邊
cut(x, y),使x和y斷邊。使x為根后,y的父親一定指向x,深度相差一定是1。當(dāng)access(y),splay(y)以后,x一定是y的左兒子,直接雙向斷開(kāi)連接。如果不一定存在該邊,先判一下連通性(注意findroot(y)以后x成了根),再看看x,y是否有父子關(guān)系,還要看y是否有左兒子(因?yàn)橐部赡躽的父親還是x,那么其它的點(diǎn)就在y的左子樹(shù)中)。
下面是LCT部分:
inline void access(int x) {for(register int y = root; x; y = x, x = t[x].fa) {// cout << "QAQ" << endl;splay(x);t[x].son[1] = y;pushup(x);// cout << "QAQ" << endl;} } // 將該節(jié)點(diǎn)到該節(jié)點(diǎn)所在Splay的根節(jié)點(diǎn)上的所有路徑都變?yōu)橹剡卛nline void makeroot(int x) {access(x); splay(x);reverse(x); } // 將一個(gè)節(jié)點(diǎn)變成所在Splay的根inline int findroot(int x) {access(x); splay(x);while(t[x].son[0]) {pushdown(x);x = t[x].son[0];}splay(x);return x; } // 找到所在Splay的根節(jié)點(diǎn)inline void split(int x, int y) {makeroot(x);access(y); splay(y); } // 分離出x到y(tǒng)的路徑inline void link(int x, int y) {makeroot(x);if(findroot(y) == x) return ;t[x].fa = y; } // 連邊inline void cut(int x, int y) {makeroot(x);if(findroot(y) != x || t[y].fa != x || t[y].son[0]) return ;t[y].fa = t[x].son[1] = 0;pushup(x); } // 斷邊主程序:
int main() {int n = read(), m = read();for(register int i = 1; i <= n; i++) {t[i].val = read();}while(m--) {int opt = read(), x = read(), y = read();if(!opt) {split(x, y);write(t[y].s), putchar(10);}if(opt == 1) {link(x, y);}if(opt == 2) {cut(x, y);}if(opt == 3) {splay(x);t[x].val = y;}}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/iycc/p/10440647.html
總結(jié)
以上是生活随笔為你收集整理的Link Cut Tree学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: css : 使用浮动实现左右各放一个元
- 下一篇: verilog中timescale