洛谷P3690 【模板】Link Cut Tree (動態樹)
阿新 • • 發佈:2019-02-05
不開o2優化就要TLE,不知道為啥。
//#include <bits/stdc++.h> #pragma GCC optimize(2) #include<stdio.h> #include<string.h> #include<string> #include<math.h> #include<algorithm> #include<iostream> #include<queue> #include<vector> #include<stack> #include<map> #include<set> #include<stdlib.h> #include<time.h> #include <iomanip> #define lowbit(x) (x&(-x)) #define inf 0x7fffffff #define linf 0x7fffffffffffffff #define mem(x,y) memset(x,y,sizeof(x)) #define fup(i,x,y) for(int i=(x);i<=(y);i++) #define fdn(i,x,y) for(int i=(x);i>=(y);i--) #define sp(x) setprecision(x) #define sd(n) scanf("%d",&n) #define sdd(n,m) scanf("%d%d",&n,&m) #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k) #define sld(n) scanf("%lld",&n) #define sldd(n,m) scanf("%lld%lld",&n,&m) #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k) #define sf(n) scanf("%lf",&n) #define sff(n,m) scanf("%lf%lf",&n,&m) #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k) #define sc(n) scanf("%s",n) #define pf(x) printf("%d\n",x) #define pfl(x) printf("%lld\n",x) #define pff(x) printf("%lf\n",x) #define debug printf("!!\n"); #define N 300005 #define M 4000009 #define pi acos(-1) #define eps 1e-2 //cout.setf(ios::fixed); //freopen("out.txt","w",stdout);// freopen("in.txt","r",stdin); using namespace std; typedef long long ll; typedef double db; const int mod=1e9+7; struct node { public:int fa,son[2],shu,sum; bool Reverse; void ini() { fa=son[0]=son[1]=Reverse=0; } }t[N]; int n,m,fa[N]; inline bool is_root(int x) { int fa=t[x].fa; return (t[fa].son[0]!=x&&t[fa].son[1]!=x); } inline void pushreverse(int x) { if(!x) return ; swap(t[x].son[0],t[x].son[1]); t[x].Reverse^=1; } inline void update(int x) { t[x].sum=t[x].shu; int l=t[x].son[0],r=t[x].son[1]; if(l) t[x].sum^=t[l].sum; if(r) t[x].sum^=t[r].sum; } inline void pushdown(int x) { if(t[x].Reverse) { pushreverse(t[x].son[0]); pushreverse(t[x].son[1]); t[x].Reverse=false; } } inline int get(int x) { return x==t[t[x].fa].son[1]; } inline void Rotate(int x) { if(is_root(x)) return; int k=get(x),fa=t[x].fa,fafa=t[fa].fa; if(!is_root(fa)) t[fafa].son[fa==t[fafa].son[1]]=x; t[fa].son[k]=t[x].son[k^1]; if(t[x].son[k^1]) t[t[x].son[k^1]].fa=fa; t[x].son[k^1]=fa; t[fa].fa=x; t[x].fa=fafa; update(x); update(fa); } inline void push(int x) { if(!is_root(x)) push(t[x].fa); pushdown(x); } inline void splay(int x) { push(x); for(int fa;!is_root(x);Rotate(x)) { fa=t[x].fa; // cout<<x<<' '<<fa<<' '<<is_root(fa)<<' '<<t[0].son[0]<<' '<<t[0].son[1]<<endl; if(!is_root(fa)) Rotate(get(x)==get(fa)?fa:x); } } inline void access(int x) { int y=0; do { splay(x); // t[t[x].son[1]].is_root=true; t[x].son[1]=y; // t[y].fa=x; update(x); x=t[y=x].fa; }while(x); } inline void mroot(int x) { access(x); splay(x); pushreverse(x); // update(x); } inline int findroot(int x) { while(t[x].fa) x=t[x].fa; return x; } inline void link(int u,int v) { mroot(u); if(findroot(v)!=u)t[u].fa=v; // update(u); } inline void cut(int u,int v) { mroot(u); access(v); splay(v); if(t[v].son[0]!=u) return ; t[u].fa=t[v].son[0]=0; update(v); } int main() { int m; sdd(n,m); // fup(i,1,n) // t[i].ini(); fup(i,1,n) { sd(t[i].shu); t[i].sum=t[i].shu; } while(m--) { int f, x,y; sddd(f,x,y); if(!f) { mroot(x); access(y); splay(y); update(y); pf(t[y].sum); } else if(f==1) { link(x,y); } else if(f==2) { cut(x,y); } else { splay(x); t[x].shu=y; update(x); } } }