洛谷P3690 Link Cut Tree (动态树)

干脆整个LCT模板吧。

缺个链上修改和子树操作,链上修改的话join(u,v)然后把v splay到树根再打个标记就好。

至于子树操作...以后有空的话再学(咕咕咕警告)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1e5+10;
 5 int n,m,a[N],Xor[N],fa[N],ch[N][2],flp[N],sta[N],tp;
 6 #define l(u) ch[u][0]
 7 #define r(u) ch[u][1]
 8 void rev(int u) {flp[u]^=1,swap(l(u),r(u));}
 9 void pu(int u) {Xor[u]=Xor[l(u)]^a[u]^Xor[r(u)];}
10 void pd(int u) {if(flp[u])rev(l(u)),rev(r(u)),flp[u]=0;}
11 int sf(int u) {return u==r(fa[u]);}
12 bool isrt(int u) {return u!=l(fa[u])&&u!=r(fa[u]);}
13 void rot(int u) {
14     int v=fa[u],f=sf(u);
15     if(!isrt(v))ch[fa[v]][sf(v)]=u;
16     ch[v][f]=ch[u][f^1],fa[ch[v][f]]=v;
17     fa[u]=fa[v],ch[u][f^1]=v,fa[v]=u,pu(v);
18 }
19 void splay(int u) {
20     sta[tp=0]=u;
21     for(int v=u; !isrt(v); v=fa[v])sta[++tp]=fa[v];
22     for(; ~tp; pd(sta[tp--]));
23     for(; !isrt(u); rot(u))if(!isrt(fa[u])&&sf(fa[u])==sf(u))rot(fa[u]);
24     pu(u);
25 }
26 void access(int u) {for(int v=0; u; splay(u),r(u)=v,pu(u),u=fa[v=u]);}
27 void makert(int u) {access(u),splay(u),rev(u);}
28 void join(int u,int v) {makert(u),access(v),splay(v);}
29 int findrt(int u) {access(u),splay(u); for(; l(u); pd(u),u=l(u)); splay(u); return u;}
30 void link(int u,int v) {makert(u); if(findrt(v)==u)return; fa[u]=v;}
31 void cut(int u,int v) {join(u,v); if(l(v)!=u||r(u))return; fa[u]=l(v)=0;}
32 void upd(int u,int x) {makert(u),a[u]=x;}
33 int qry(int u,int v) {join(u,v); return Xor[v];}
34 int main() {
35     scanf("%d%d",&n,&m);
36     for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
37     while(m--) {
38         int f,x,y;
39         scanf("%d%d%d",&f,&x,&y);
40         if(f==0)printf("%d
",qry(x,y));
41         else if(f==1)link(x,y);
42         else if(f==2)cut(x,y);
43         else if(f==3)upd(x,y);
44     }
45     return 0;
46 }
原文地址:https://www.cnblogs.com/asdfsag/p/11632199.html