[模板]Link Cut Tree
阿新 • • 發佈:2019-01-27
復雜 while gist 模板題 reg des pap register acc
傳送門
Description
給定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。
Solution
\(Link\ Cut\ Tree\)模板題
\(findroot\)後要\(Splay\)到根?不然復雜度不保證???
在洛谷上實測\(535ms\)
,還算比較快吧函數變量名奇異+神仙縮行\(\rightarrow\) 還是別看了
Code?
//2019.1.26 18:41-22:54 #include<bits/stdc++.h> inline int read() { register int x=0,f=1;register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } class Link_Cut_Tree { #define MN 300005 private: int N,fa[MN],c[MN][2],st[MN],val[MN],X[MN]; bool rev[MN]; inline bool nrt(int x){return c[fa[x]][0]==x||c[fa[x]][1]==x;} inline void Rev(int x){rev[x]^=1;std::swap(c[x][0],c[x][1]);} inline void up(int x){X[x]=X[c[x][0]]^X[c[x][1]]^val[x];} inline void down(int x){if(x&&rev[x])Rev(c[x][0]),Rev(c[x][1]),rev[x]=0;} #define get(x) (c[fa[x]][1]==x) inline void rotate(int x) { int y=fa[x],z=fa[y],l=get(x),r=l^1;if(nrt(y))c[z][get(y)]=x;fa[x]=z; c[y][l]=c[x][r];fa[c[x][r]]=y;c[x][r]=y;fa[y]=x;up(y); } inline void Splay(int x) { static int top,q[MN];q[top=1]=x;register int i; for(i=x;nrt(i);i=fa[i]) q[++top]=fa[i];for(;top;--top) down(q[top]); for(;nrt(x);rotate(x))if(nrt(fa[x])) rotate(get(fa[x])^get(x)?x:fa[x]);up(x); } #undef get inline void access(int x){register int i;for(i=0;x;x=fa[i=x])Splay(x),c[x][1]=i,up(x);} inline void mkrt(int x){access(x);Splay(x);Rev(x);} inline int fdrt(int x){access(x),Splay(x);for(;c[x][0];down(c[x][0]),x=c[x][0]);Splay(x);return x;} inline void Split(int x,int y){mkrt(x);access(y);Splay(y);} public: inline void init(int n){register int i;for(i=1;i<=n;++i) val[i]=X[i]=read();} void Link(int x,int y){mkrt(x);if(fdrt(y)!=x)fa[x]=y;} void Cut(int x,int y){Split(x,y);if(c[y][0]==x&&!c[x][1])c[y][0]=fa[x]=0,up(y);} inline int Query(int x,int y){if(x==y) return val[x];Split(x,y);return X[y];} inline void Modify(int x,int V){Splay(x);val[x]=V;up(x);} #undef MN }T; int main() { register int n=read(),m=read(),opt,x;T.init(n); while(m--) { opt=read(),x=read(); switch(opt) { case 0:printf("%d\n",T.Query(x,read()));break; case 1:T.Link(x,read());break; case 2:T.Cut(x,read());break; case 3:T.Modify(x,read());break; } } }
Blog來自PaperCloud,未經允許,請勿轉載,TKS!
[模板]Link Cut Tree