bzoj4530 [Bjoi2014]大融合

LCT维护子树size

具体维护子树信息请看我的少女

  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 */
View Code

 

posted @ 2018-01-03 11:47  Ren_Ivan  阅读(184)  评论(0编辑  收藏  举报