[模板]Link-Cut-Tree动态树
做法以后再补,先写一些注意事项。
做法以后也不补了,直接看这个吧。https://www.cnblogs.com/candy99/p/6271344.html
1.rotate其实是最容易写错的地方(对于丝毫没有掌握splay蒟蒻我来说),一定要仔细检查
2.splay之前需要先从根开始往下pushdown一遍
3.注意getRoot(findRoot)和setRoot(makeRoot)对节点位置带来的影响
4.access的结束条件是x==0!!不是fa[x]!!(这个zz才会写错吧) (没错就是我写错了还查了半天)
5.pushdown的位置、是否splay(x)所带来的玄学问题(我哪想的明白啊)
luogu3690(连边、断边、改点值、查询链上异或和)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<map> 7 #include<cmath> 8 #include<ctime> 9 #include<set> 10 #define pa pair<int,int> 11 #define lowb(x) ((x)&(-(x))) 12 #define REP(i,n0,n) for(i=n0;i<=n;i++) 13 #define PER(i,n0,n) for(i=n;i>=n0;i--) 14 #define MAX(a,b) ((a>b)?a:b) 15 #define MIN(a,b) ((a<b)?a:b) 16 #define CLR(a,x) memset(a,x,sizeof(a)) 17 #define rei register int 18 using namespace std; 19 typedef long long ll; 20 const int maxn=300050; 21 22 ll rd(){ 23 ll x=0;char c=getchar();int neg=1; 24 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 25 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 26 return x*neg; 27 } 28 29 int N,M; 30 int ch[maxn][2],v[maxn],xs[maxn],fa[maxn]; 31 bool rev[maxn]; 32 33 inline void pushrev(int x){swap(ch[x][0],ch[x][1]);rev[x]^=1;} 34 inline void update(int x){xs[x]=xs[ch[x][0]]^xs[ch[x][1]]^v[x];} 35 inline void pushdown(int x){ 36 if(!rev[x]) return; 37 if(ch[x][0]) pushrev(ch[x][0]); 38 if(ch[x][1]) pushrev(ch[x][1]); 39 rev[x]=0; 40 } 41 inline bool isRoot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 42 inline bool isRson(int x){return x==ch[fa[x]][1];} 43 inline void rotate(int x){ 44 int f=fa[x],ff=fa[f];bool b=isRson(x); 45 if(ch[x][b^1]) fa[ch[x][b^1]]=f;ch[f][b]=ch[x][b^1]; 46 if(!isRoot(f)) ch[ff][isRson(f)]=x;fa[x]=ff; 47 fa[f]=x;ch[x][b^1]=f;update(f);update(x); 48 } 49 void pushall(int x){ 50 if(!isRoot(x)) pushall(fa[x]); 51 pushdown(x); 52 } 53 inline void splay(int x){ 54 pushall(x); 55 while(!isRoot(x)&&!isRoot(fa[x])){ 56 if(isRson(x)==isRson(fa[x])) rotate(fa[x]);rotate(x); 57 }if(!isRoot(x)) rotate(x); 58 } 59 inline void access(int x){ 60 for(int lst=0;x;lst=x,x=fa[x]){ 61 splay(x);ch[x][1]=lst;update(x); 62 } 63 } 64 inline int getRoot(int x){ 65 access(x);splay(x); 66 while(ch[x][0]){pushdown(x);x=ch[x][0];}return x; 67 } 68 inline void setRoot(int x){ 69 access(x);splay(x);pushrev(x); 70 } 71 inline void link(int x,int y){ 72 setRoot(x); 73 if(getRoot(y)!=x) fa[x]=y; 74 } 75 inline void cut(int x,int y){ 76 setRoot(x); 77 if(getRoot(y)!=x||fa[x]!=y||ch[x][1]) return; 78 ch[y][0]=fa[x]=0;update(y); 79 } 80 inline void change(int x,int k){ 81 splay(x);v[x]=k;update(x); 82 } 83 inline int query(int x,int y){ 84 setRoot(x);access(y);splay(y); 85 return xs[y]; 86 } 87 88 int main(){ 89 //freopen("testdata.in","r",stdin); 90 rei i,j,k; 91 N=rd(),M=rd();//printf("%d %d\n",N,M); 92 for(i=1;i<=N;i++) v[i]=xs[i]=rd(); 93 while(M--){ 94 int a=rd(),x=rd(),y=rd(); 95 if(a==0) printf("%d\n",query(x,y)); 96 else if(a==1) link(x,y); 97 else if(a==2) cut(x,y); 98 else if(a==3) change(x,y); 99 } 100 return 0; 101 }
luogu3203 弹飞绵羊(连边、断边、查询链长)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<map> 7 #include<cmath> 8 #include<ctime> 9 #include<set> 10 #define pa pair<int,int> 11 #define lowb(x) ((x)&(-(x))) 12 #define REP(i,n0,n) for(i=n0;i<=n;i++) 13 #define PER(i,n0,n) for(i=n;i>=n0;i--) 14 #define MAX(a,b) ((a>b)?a:b) 15 #define MIN(a,b) ((a<b)?a:b) 16 #define CLR(a,x) memset(a,x,sizeof(a)) 17 #define rei register int 18 #define lt ch[x][0] 19 #define rt ch[x][1] 20 using namespace std; 21 const int maxn=200020; 22 typedef long long ll; 23 24 ll rd(){ 25 ll x=0;char c=getchar();int neg=1; 26 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 27 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 28 return x*neg; 29 } 30 31 int N,M; 32 int fa[maxn],ch[maxn][2],siz[maxn],to[maxn]; 33 bool rev[maxn]; 34 35 inline void update(int x){siz[x]=(lt?siz[lt]:0)+(rt?siz[rt]:0)+1;} 36 inline void pushrev(int x){ 37 rev[x]^=1;swap(lt,rt); 38 } 39 inline void pushdown(int x){ 40 if(!rev[x]) return; 41 if(lt) pushrev(lt); 42 if(rt) pushrev(rt); 43 rev[x]=0; 44 } 45 inline bool isRoot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 46 inline bool isRson(int x){return x==ch[fa[x]][1];} 47 inline void rotate(int x){ 48 int f=fa[x],ff=fa[f];bool b=isRson(x); 49 if(!isRoot(f)) ch[ff][isRson(f)]=x;fa[x]=ff; 50 if(ch[x][b^1]) fa[ch[x][b^1]]=f;ch[f][b]=ch[x][b^1]; 51 ch[x][b^1]=f;fa[f]=x;update(f);update(x); 52 } 53 inline void pushdall(int x){ 54 if(!isRoot(x)) pushdall(fa[x]);pushdown(x); 55 } 56 inline void splay(int x){ 57 pushdall(x); 58 while(!isRoot(x)&&!isRoot(fa[x])){ 59 if(isRson(x)==isRson(fa[x])) rotate(fa[x]); 60 else rotate(x);rotate(x); 61 }if(!isRoot(x)) rotate(x); 62 } 63 inline void access(int x){ 64 for(int y=0;x;y=x,x=fa[x]){ 65 splay(x);rt=y;update(x); 66 } 67 } 68 inline void setRoot(int x){ 69 access(x);splay(x); 70 pushrev(x); 71 } 72 inline int getRoot(int x){ 73 access(x);splay(x); 74 while(lt){ 75 pushdown(x);x=lt; 76 }return x; 77 } 78 inline void link(int x,int y){//x->y 79 setRoot(x); 80 access(y);splay(y);fa[x]=y; 81 } 82 inline void cut(int x,int y){ 83 setRoot(x);access(y);splay(y); 84 ch[y][0]=fa[x]=0;update(y); 85 } 86 inline int query(int x,int y){ 87 setRoot(x); 88 access(y);splay(y); 89 //printf("%d %d\n",ch[y][0],ch[y][1]); 90 return siz[y]; 91 } 92 inline void change(int x,int k){ 93 if(x+k>N&&x+to[x]>N) return; 94 if(to[x]) cut(x,MIN(x+to[x],N+1)); 95 link(x,MIN(x+k,N+1)); 96 to[x]=k; 97 } 98 99 int main(){ 100 //freopen("3203.in","r",stdin); 101 rei i,j,k;N=rd(); 102 REP(i,1,N) change(i,rd()),siz[i]=1;siz[N+1]=1; 103 M=rd();REP(i,1,M){ 104 j=rd(),k=rd()+1; 105 if(j==1) printf("%d\n",query(N+1,k)-1); 106 else change(k,rd()); 107 } 108 return 0; 109 }