洛谷P3690 [模板] Link Cut Tree [LCT]
阿新 • • 發佈:2018-06-28
con radi 復制 blank clas microsoft 博客 push ()
題目傳送門
Link Cut Tree
題目背景
動態樹
題目描述
給定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 1 2 3 1 1 2 0 1 2 0 1 1輸出樣例#1: 復制
3 1
說明
數據範圍: 1$ \leq $ N,M $ \leq $ 3 · $ 10^5 $
分析:
Link Cut Tree模板題。具體的知識點這位大佬已經講的特別好了,推薦這位大佬的博客<http://www.cnblogs.com/flashhu/p/8324551.html>,蒟蒻就只放代碼了。
Code:
1 //It is made by HolseLee on 27th June 2018 2 //Luogu.org P3690 3 #include<bits/stdc++.h> 4 using namespace std; 5 const int N=3e5+7; 6 int n,m,val[N]; 7 struct LCT{ 8 int fa[N],ch[N][2],xr[N],sign[N],q[N],top; 9 inline void pushup(int u) 10 {11 xr[u]=xr[ch[u][0]]^xr[ch[u][1]]^val[u]; 12 } 13 inline void change(int u) 14 { 15 int temp=ch[u][0]; 16 ch[u][0]=ch[u][1]; 17 ch[u][1]=temp; 18 sign[u]^=1; 19 } 20 inline void pushdown(int u) 21 { 22 if(!sign[u])return; 23 if(ch[u][0])change(ch[u][0]); 24 if(ch[u][1])change(ch[u][1]); 25 sign[u]=0; 26 } 27 inline bool isroot(int u) 28 { 29 return (ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u); 30 } 31 inline void rotate(int x) 32 { 33 int y=fa[x],z=fa[y]; 34 int k=(ch[y][1]==x); 35 int w=ch[x][k^1]; 36 if(!isroot(y))ch[z][ch[z][1]==y]=x; 37 ch[x][k^1]=y;ch[y][k]=w; 38 if(w)fa[w]=y;fa[y]=x;fa[x]=z; 39 pushup(y);pushup(x); 40 } 41 inline void splay(int x) 42 { 43 top=1;q[top]=x; 44 for(int i=x;!isroot(i);i=fa[i]) 45 q[++top]=fa[i]; 46 while(top)pushdown(q[top--]); 47 while(!isroot(x)){ 48 int y=fa[x],z=fa[y]; 49 if(!isroot(y)) 50 (ch[y][0]==x)^(ch[z][0]==y)?rotate(x):rotate(y); 51 rotate(x); 52 } 53 } 54 void access(int u) 55 { 56 for(int i=0;u;i=u,u=fa[u]){ 57 splay(u);ch[u][1]=i;pushup(u);} 58 } 59 void makeroot(int u) 60 { 61 access(u);splay(u);change(u); 62 } 63 inline int find(int u) 64 { 65 access(u);splay(u); 66 while(ch[u][0])pushdown(u),u=ch[u][0]; 67 splay(u); 68 return u; 69 } 70 void split(int u,int v) 71 { 72 makeroot(u);access(v);splay(v); 73 } 74 void cut(int u,int v) 75 { 76 makeroot(u); 77 if(find(v)==u&&fa[v]==u&&!ch[v][0]){ 78 fa[v]=ch[u][1]=0;pushup(u);} 79 } 80 void link(int u,int v) 81 { 82 makeroot(u); 83 if(find(v)!=u)fa[u]=v; 84 } 85 }T; 86 inline int read() 87 { 88 char ch=getchar();int num=0;bool flag=false; 89 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)flag=true;ch=getchar();} 90 while(ch>=‘0‘&&ch<=‘9‘){num=num*10+ch-‘0‘;ch=getchar();} 91 return flag?-num:num; 92 } 93 int main() 94 { 95 n=read();m=read();int opt,x,y; 96 for(int i=1;i<=n;i++){ 97 val[i]=read();T.xr[i]=val[i];} 98 for(int i=1;i<=m;i++){ 99 opt=read();x=read();y=read(); 100 if(opt==0){ 101 T.split(x,y); 102 printf("%d\n",T.xr[y]);} 103 else if(opt==1){T.link(x,y);} 104 else if(opt==2){T.cut(x,y);} 105 else if(opt==3){ 106 T.splay(x);val[x]=y;T.pushup(x);} 107 } 108 return 0; 109 }
洛谷P3690 [模板] Link Cut Tree [LCT]