bzoj4530 [Bjoi2014]大融合
LCT维护子树size
具体维护子树信息请看我的少女
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #define N 100005 7 using namespace std; 8 struct Node{ 9 Node *ch[2],*fa; 10 int sum,sxu,rev,id; 11 Node (); 12 void Rev(); 13 void pushup(); 14 void pushdown(); 15 }*null=new Node,tree[N]; 16 Node :: Node(){ 17 ch[0]=ch[1]=fa=null; 18 sum=1;sxu=rev=id=0; 19 } 20 void Node :: Rev(){ 21 rev^=1; 22 swap(ch[0],ch[1]); 23 } 24 void Node :: pushup(){ 25 sum=ch[0]->sum+ch[1]->sum+sxu+1; 26 } 27 void Node :: pushdown(){ 28 if(rev){ 29 ch[0]->Rev(); 30 ch[1]->Rev(); 31 rev=0; 32 } 33 } 34 void rotate(Node *x){ 35 Node *y=x->fa,*z=y->fa; 36 int w=y->ch[1]==x; 37 y->ch[w]=x->ch[w^1];x->ch[w^1]->fa=y; 38 x->ch[w^1]=y;y->fa=x; 39 if(z->ch[0]==y)z->ch[0]=x; 40 if(z->ch[1]==y)z->ch[1]=x; 41 x->fa=z; 42 y->pushup();x->pushup(); 43 } 44 bool isroot(Node *x){ 45 return (x->fa->ch[0]!=x)&&(x->fa->ch[1]!=x); 46 } 47 void splay(Node *x){ 48 Node *y,*z; 49 x->pushdown(); 50 while(!isroot(x)){ 51 y=x->fa;z=y->fa; 52 z->pushdown();y->pushdown();x->pushdown(); 53 if((z->ch[0]==y&&y->ch[0]==x)||(z->ch[1]==y&&y->ch[1]==x)) 54 rotate(y); 55 rotate(x); 56 } 57 } 58 void access(Node *x){ 59 Node *y=null; 60 while(x!=null){ 61 splay(x); 62 x->sxu+=x->ch[1]->sum-y->sum; 63 x->ch[1]=y; 64 x->pushup(); 65 y=x;x=x->fa; 66 } 67 } 68 void make_root(Node *x){ 69 access(x); 70 splay(x); 71 x->Rev(); 72 } 73 void link(Node *x,Node *y){ 74 make_root(x); 75 make_root(y); 76 x->fa=y; 77 y->sxu+=x->sum; 78 y->pushup(); 79 } 80 long long query(Node *x,Node *y){ 81 make_root(x); 82 make_root(y); 83 return 1ll*((y->sum)-(x->sum))*(x->sum); 84 } 85 int n,m; 86 int main(){ 87 null->ch[0]=null->ch[1]=null->fa=null; 88 null->sum=null->sxu=null->rev=null->id=0; 89 scanf("%d%d",&n,&m); 90 char ch[2]; 91 int x,y; 92 for(int i=1;i<=n;i++) 93 tree[i].id=i; 94 while(m--){ 95 scanf("%s%d%d",ch,&x,&y); 96 if(ch[0]=='A') link(&tree[x],&tree[y]); 97 else printf("%lld\n",query(&tree[x],&tree[y])); 98 } 99 } 100 /* 101 10 1000 102 A 1 2 103 A 1 5 104 Q 1 2 105 A 2 3 106 Q 1 2 107 Q 1 5 108 A 5 6 109 A 5 7 110 Q 1 5 111 Q 2 3 112 A 3 4 113 A 4 8 114 A 8 9 115 A 9 10 116 Q 3 4 117 Q 4 8 118 Q 8 9 119 Q 9 10 120 */
人生如梦亦如幻 朝如晨露暮如霞。