[模板]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 }
luogu3690

 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 }
luogu3203

 

posted @ 2018-09-06 22:37  Ressed  阅读(204)  评论(0编辑  收藏  举报