BZOJ2049: [Sdoi2008]Cave 洞穴勘测
n<=10000个点,m<=200000个操作,连接,断边,问两个点是否连通,保证连接过程中每个联通块都是树。
LCT。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<string.h> 2 #include<stdlib.h> 3 #include<stdio.h> 4 #include<math.h> 5 //#include<assert.h> 6 #include<algorithm> 7 //#include<iostream> 8 //#include<bitset> 9 using namespace std; 10 11 int n,m; 12 #define maxn 10011 13 struct LCT 14 { 15 struct Node 16 { 17 int fa,son[2]; 18 bool rev; 19 int size; 20 }a[maxn]; 21 void makeatree(int id) 22 { 23 a[id].fa=a[id].son[0]=a[id].son[1]=a[id].rev=0; 24 a[id].size=1; 25 } 26 void up(int x) 27 { 28 if (!x) return; 29 int &p=a[x].son[0],&q=a[x].son[1]; 30 a[x].size=a[p].size+a[q].size+1; 31 } 32 void revsingle(int x) 33 { 34 if (!x) return; 35 a[x].rev^=1; 36 int &p=a[x].son[0],&q=a[x].son[1]; 37 p^=q; q^=p; p^=q; 38 } 39 void down(int x) 40 { 41 int &p=a[x].son[0],&q=a[x].son[1]; 42 if (a[x].rev) {revsingle(p); revsingle(q); a[x].rev=0;} 43 } 44 int sta[maxn]; 45 void download(int x) 46 { 47 int top=0; for (;!isroot(x);x=a[x].fa) sta[++top]=x; sta[++top]=x; 48 for (;top;top--) down(sta[top]); 49 } 50 bool isroot(int x) 51 { 52 if (!a[x].fa) return 1; 53 return (a[a[x].fa].son[0]!=x && a[a[x].fa].son[1]!=x); 54 } 55 void rotate(int x) 56 { 57 const int y=a[x].fa,z=a[y].fa; 58 bool w=(x==a[y].son[0]); 59 a[x].fa=z; 60 if (!isroot(y)) a[z].son[y==a[z].son[1]]=x; 61 a[y].son[w^1]=a[x].son[w]; 62 if (a[x].son[w]) a[a[x].son[w]].fa=y; 63 a[x].son[w]=y; 64 a[y].fa=x; 65 up(y); up(z); 66 } 67 void splay(int x) 68 { 69 if (!x) return; 70 download(x); 71 while (!isroot(x)) 72 { 73 const int y=a[x].fa,z=a[y].fa; 74 if (!isroot(y)) 75 { 76 if ((x==a[y].son[0])^(y==a[z].son[0])) rotate(x); 77 else rotate(y); 78 } 79 rotate(x); 80 } 81 up(x); 82 } 83 void access(int x) 84 { 85 int y=0,tmp=x; 86 while (x) {splay(x); a[x].son[1]=y; up(x); y=x; x=a[x].fa;} 87 splay(tmp); 88 } 89 void resetroot(int x) 90 { 91 access(x); 92 revsingle(x); 93 } 94 void link(int x,int y) 95 { 96 resetroot(x); 97 a[x].fa=y; 98 } 99 void cut(int x,int y) 100 { 101 resetroot(x); 102 access(y); 103 a[y].son[0]=a[x].fa=0; 104 up(y); 105 } 106 int findroot(int x) 107 { 108 while (a[x].fa) x=a[x].fa; 109 return x; 110 } 111 }t; 112 113 int main() 114 { 115 scanf("%d%d",&n,&m); 116 for (int i=1;i<=n;i++) t.makeatree(i); 117 char c;int x,y; 118 while (m--) 119 { 120 while ((c=getchar())!='C' && c!='D' && c!='Q'); 121 if (c=='C') 122 { 123 while ((c=getchar())>='a' && c<='z'); 124 scanf("%d%d",&x,&y); 125 t.link(x,y); 126 } 127 else if (c=='D') 128 { 129 while ((c=getchar())>='a' && c<='z'); 130 scanf("%d%d",&x,&y); 131 t.cut(x,y); 132 } 133 else if (c=='Q') 134 { 135 while ((c=getchar())>='a' && c<='z'); 136 scanf("%d%d",&x,&y); 137 puts(t.findroot(x)==t.findroot(y)?"Yes":"No"); 138 } 139 } 140 return 0; 141 }