luogu 3690 【模板】 Link Cut Tree (动态树)
原来的代码有一些问题。
主要是对于不一定存在的边如何去判断,首先要保证在一个splay里,然后保证彼此之间直接联通且x的右儿子是空的
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #define ll long long 12 #define inf 2139062143 13 #define MAXN 300100 14 #define MOD 998244353 15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i) 16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i) 17 #define ren for(register int i=fst[x];i;i=nxt[i]) 18 #define pb(i,x) vec[i].push_back(x) 19 #define pls(a,b) (a+b)%MOD 20 #define mns(a,b) (a-b+MOD)%MOD 21 #define mul(a,b) (1LL*(a)*(b))%MOD 22 using namespace std; 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 27 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 28 return x*f; 29 } 30 int n,m; 31 int ch[MAXN][2],tag[MAXN],sum[MAXN],val[MAXN],fa[MAXN]; 32 struct Lct 33 { 34 int which(int x) {return ch[fa[x]][1]==x;} 35 int isroot(int x) {return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 36 void upd(int x) {sum[x]=val[x]^sum[ch[x][0]]^sum[ch[x][1]];} 37 void rev(int x) {tag[x]^=1;swap(ch[x][0],ch[x][1]);} 38 void pshd(int x) 39 { 40 if(!tag[x]) return ;tag[x]^=1; 41 if(ch[x][0]) rev(ch[x][0]); 42 if(ch[x][1]) rev(ch[x][1]); 43 } 44 void rotate(int x) 45 { 46 int f=fa[x],ff=fa[f],k=which(x); 47 if(!isroot(f)) ch[ff][ch[ff][1]==f]=x;fa[x]=ff; 48 ch[f][k]=ch[x][k^1],fa[ch[f][k]]=f,ch[x][k^1]=f,fa[f]=x; 49 upd(f);upd(x); 50 } 51 int st[MAXN],top; 52 void splay(int x) 53 { 54 st[top=1]=x; 55 for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; 56 dwn(i,top,1) pshd(st[i]); 57 for(int f;!isroot(x);rotate(x)) 58 if(!isroot(f=fa[x])) rotate(which(x)==which(f)?f:x); 59 } 60 void access(int x) {for(int t=0;x;t=x,x=fa[x]){splay(x);ch[x][1]=t;upd(x);}} 61 void mkrt(int x) {access(x);splay(x);rev(x);} 62 void link(int x,int y) {mkrt(x);fa[x]=y;} 63 void split(int x,int y) {mkrt(x);access(y);splay(y);} 64 int find(int x) 65 { 66 access(x);splay(x); 67 while(ch[x][0]) pshd(x),x=ch[x][0];return x; 68 } 69 void cut(int x,int y) {split(x,y);if(fa[x]==y&&ch[y][0]==x&&!ch[x][1]) ch[y][0]=fa[x]=0,upd(y);} 70 }lct; 71 int main() 72 { 73 n=read(),m=read();int t,a,b;rep(i,1,n) val[i]=read(); 74 while(m--) 75 { 76 t=read(),a=read(),b=read(); 77 if(!t) {lct.split(a,b);printf("%d\n",sum[b]);} 78 if(t==1&&lct.find(a)!=lct.find(b)) lct.link(a,b); 79 if(t==2&&lct.find(a)==lct.find(b)) lct.cut(a,b); 80 if(t==3) val[a]=b,splay(a); 81 } 82 }