洛谷P2147 SDOI2008 洞穴勘測 (LCT)
阿新 • • 發佈:2022-04-04
大模板
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e4+5; 4 int n,m,a[N],w[N]; 5 struct node{ 6 int fa,lc,rc,rv; 7 #define lc(x) t[x].lc 8 #define rc(x) t[x].rc 9 #define fa(x) t[x].fa 10 #define rv(x) t[x].rv 11 }t[N]; 12 13 bool isr(intx)//isroot 14 { 15 return lc(fa(x))!=x&&rc(fa(x))!=x; 16 } 17 bool wrt(int x){ 18 return rc(fa(x))==x; 19 } 20 21 void rev(int x){//做標記 22 if(!x) return; 23 swap(lc(x),rc(x)); 24 rv(x)^=1; 25 } 26 27 void down(int x){//下傳標記 28 if(rv(x)){ 29 rev(lc(x)),rev(rc(x));30 } 31 rv(x)=0; 32 } 33 34 void rot(int x){//旋轉 35 int y=fa(x),z=fa(y),b=(lc(y)==x)?rc(x):lc(x); 36 if(z&&!isr(y)) (lc(z)==y?lc(z):rc(z))=x; 37 fa(x)=z,fa(y)=x; 38 if(b) fa(b)=y; 39 if(lc(y)==x) rc(x)=y,lc(y)=b; 40 else lc(x)=y,rc(y)=b; 41 } 42 43void path(int x){//根到節點上的點都下傳標記 44 if(!isr(x)) path(fa(x)); 45 down(x); 46 } 47 48 void spl(int x){//splay 49 path(x); 50 while(!isr(x)){ 51 if(!isr(fa(x))) wrt(x)==wrt(fa(x))?rot(fa(x)):rot(x); 52 rot(x); 53 } 54 } 55 56 void acs(int x){ 57 for(int y=0;x;y=x,x=fa(x)){ 58 spl(x),rc(x)=y; 59 } 60 return ; 61 } 62 63 void mrt(int x){//makeroot 64 acs(x),spl(x),rev(x); 65 } 66 67 int fnd(int x){//findroot 68 acs(x),spl(x),down(x); 69 while(lc(x)) x=lc(x),down(x); 70 spl(x);return x; 71 } 72 73 void lk(int x,int y){//link 74 mrt(x); 75 if(fnd(y)==x) return ; 76 fa(x)=y; 77 } 78 79 void cut(int x,int y){//刪邊 80 mrt(x),acs(y),spl(y); 81 if(lc(y)!=x) return ; 82 lc(y)=fa(x)=0; 83 } 84 /*char ch; 85 int read(){ 86 while(ch=getchar(),ch<'0'||ch>'9'); 87 int res=ch-48; 88 while(ch=getchar(),ch>='0'&&ch<='9') 89 res=res*10+ch-48; 90 return res; 91 }*/ 92 93 int main(){ 94 scanf("%d%d",&n,&m); 95 /*n=read(),m=read();*/ 96 for(int i=1;i<=m;i++){ 97 /*while(ch=getchar(),ch<'A'||ch>'Z');*/ 98 int x,y; 99 char a[10]; 100 scanf("%s",a+1); 101 scanf("%d%d",&x,&y); 102 if(a[1]=='Q'){ 103 if(fnd(x)==fnd(y)) cout<<"Yes"<<endl; 104 else cout<<"No"<<endl; 105 } 106 else if(a[1]=='C') lk(x,y); 107 else cut(x,y); 108 } 109 return 0; 110 }