bzoj 2049: [Sdoi2008]Cave 洞穴勘测

  1 #include<cstdio>
  2 #include<iostream>
  3 using namespace std;
  4 int  shu[20002][2],n,m,fa[20005],st[20005];
  5 bool rev[20005];
  6 bool isroot(int a1)
  7 {
  8     return shu[fa[a1]][0]!=a1&&shu[fa[a1]][1]!=a1;
  9 }
 10 void pushdown(int a1)
 11 {
 12     int l=shu[a1][0],r=shu[a1][1];
 13     if(rev[a1])
 14       {
 15         rev[a1]^=1;
 16         rev[l]^=1;
 17         rev[r]^=1;
 18         swap(shu[a1][0],shu[a1][1]);
 19       }
 20 }
 21 void zhuan(int a1)
 22 {
 23     int y=fa[a1],z=fa[y],l,r;
 24     if(shu[y][0]==a1)
 25       l=0;
 26     else
 27       l=1;
 28     r=l^1;
 29     if(!isroot(y))
 30        if(shu[z][0]==y)
 31          shu[z][0]=a1;
 32        else
 33          shu[z][1]=a1;
 34     fa[a1]=z;
 35     fa[y]=a1;
 36     shu[y][l]=shu[a1][r];
 37     fa[shu[y][l]]=y;
 38     shu[a1][r]=y;
 39 }
 40 void splay(int a1)
 41 {
 42     int top=0;
 43     top++;
 44     st[top]=a1;
 45     for(int i=a1;!isroot(i);i=fa[i])
 46       {
 47         top++;
 48         st[top]=fa[i];
 49       }
 50     for(int i=top;i;i--)
 51       pushdown(st[i]);
 52     for(;!isroot(a1);)
 53       {
 54         int y=fa[a1],z=fa[a1];
 55         if(!isroot(y))
 56           if(y==shu[z][0]^a1==shu[y][0])
 57             zhuan(a1);
 58           else
 59             zhuan(y);
 60         zhuan(a1);
 61       }
 62 }
 63 void access(int a1)
 64 {
 65     int t=0;
 66     for(;a1;)
 67       {
 68         splay(a1);
 69         shu[a1][1]=t;
 70         t=a1;
 71         a1=fa[a1];
 72       }
 73 }
 74 void gen(int a1)
 75 {
 76     access(a1);
 77     splay(a1);
 78     rev[a1]^=1;
 79 }
 80 void lian(int a1,int a2)
 81 {
 82     gen(a1);
 83     fa[a1]=a2;
 84     splay(a1);
 85 }
 86 void cut(int a1,int a2)
 87 {
 88     gen(a1);
 89     access(a2);
 90     splay(a2);
 91     shu[a2][0]=fa[a1]=0;
 92 }
 93 int find(int a1)
 94 {
 95     access(a1);
 96     splay(a1);
 97     int y;
 98     for(y=a1;shu[y][0];y=shu[y][0]);
 99     return y;
100 }
101 int main()
102 {
103     scanf("%d%d",&n,&m);
104     for(int i=0;i<m;i++)
105       {
106         int a1,a2;
107         char ch[10];
108         scanf("%s%d%d",ch,&a1,&a2);
109         if(ch[0]=='C')
110           lian(a1,a2);
111         if(ch[0]=='D')
112           cut(a1,a2);
113         if(ch[0]=='Q')
114           {
115             int a3,a4;
116             a3=find(a1);
117             a4=find(a2);
118             if(a3==a4)
119               printf("Yes
");
120             else
121               printf("No
");
122             }
123       }
124     return 0;
125 }

link-cut-tree

原文地址:https://www.cnblogs.com/xydddd/p/5294003.html