模板Link Cut Tree (動態樹)

2022-05-10 23:17:26 字數 1824 閱讀 5007

給定n個點以及每個點的權值,要你處理接下來的m個操作。操作有4種。操作從0到3編號。點從1到n編號。

0:後接兩個整數(x,y),代表詢問從x到y的路徑上的點的權值的xor和。保證x到y是聯通的。

1:後接兩個整數(x,y),代表連線x到y,若x到y已經聯通則無需連線。

2:後接兩個整數(x,y),代表刪除邊(x,y),不保證邊(x,y)存在。

3:後接兩個整數(x,y),代表將點x上的權值變成y。

輸入格式:

第1行兩個整數,分別為n和m,代表點數和運算元。

第2行到第n+1行,每行乙個整數,整數在[1,10^9]內,代表每個點的權值。

第n+2行到第n+m+1行,每行三個整數,分別代表操作型別和操作所需的量。

輸出格式:

對於每乙個0號操作,你須輸出x到y的路徑上點權的xor和。

輸入樣例#1:複製

3 3 12

31 1 2

0 1 2

0 1 1

輸出樣例#1:複製

3

1

資料範圍: 1≤n,m≤3⋅105

演算法原理提供可靠**:

zyys

這道題用到的技巧:

找根:$makeroot(o)$後一直往左走。最後乙個節點就是根。(理由:由於$lct$中$splay$的性質:按深度作為鍵值);

判斷是否之間有邊:再$cut$之前,判斷根的左兒子是否是另外乙個點。(理由:若存在邊,則包含這條邊的$splay$只有兩個節點)。

1 #include2 #include3 #include4 #include5 #include6 #include7

using

namespace

std;

8int xr[300005],ch[300005][2],val[300005],pre[300005

],n,m;

9bool isrt[300005],rev[300005

];10

void pushup(int

o)11

15void pushdown(int

o)16

26if

(rs)

2731 rev[o]=0;32

}33}34

void push(int

o)35

40void rotate(int o,bool

kind)

4150

void splay(int

o)5164}

65}66void access(int

o)6777}

78void makeroot(int

o)79

85int find(int

o)86

93return

o;94}95

void link(int x,int

y)96

100void cut(int x,int

y)101

109int

main()

110

117for (i=1;i<=m;i++)

118127

else

if (c==1

)128

132else

if (c==2

)133

136else

if (c==3

)137

142}

143 }

動態樹初探 link cut tree

很愚昧的以為動態樹是一種資料結構,現在才知道動態樹是是一類問題 dynamic tree problems spoj上有一系列關於樹的很有趣的題目 qtree1 4 和樹鏈剖分 動態樹有關,所以就狠下心的研究了一番,多虧找到了一篇好 qtree解法的一些研究 by yangzhe 解決動態樹問題的資...

Link Cut Tree學習總結

title link cut tree學習總結 categories 演算法 date 2016 1 14 21 30 00 tags lct,演算法 lct是一種用於解決動態樹問題的資料結構。大體上的感受,lct就是樹鏈剖分和splay的結合版,什麼意思呢?因為要動態維護樹的結構和樹上的資訊,所以...

Link Cut Tree學習小記

link cut tree簡稱lct,是維護動態樹方式的一種,是乙個可以對樹進行新增鏈或子樹,刪除鏈或子樹等等,可以支援對樹的結構進行修改的演算法。樹鏈剖分只能維護靜態樹,就是只能對樹上的點的值進行修改的演算法,一般還是用線段樹來維護的。所以lct就厲害了,首先是維護方式不同,其次它是用splay來...