bzoj 2631 tree

LCT简单题,但是标记有点恶心

就当复习SPLAY了吧。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cmath>
  6 #define N 100050
  7 #define int long long
  8 #define mod 51061
  9 using namespace std;
 10 int n,m;
 11 char ch[2];
 12 struct Node{
 13     Node *ch[2],*fa;
 14     int id,now,sum,plus,times,size,rev;
 15     Node();
 16     void pushdown();
 17     void pushup();
 18 }*null=new Node,tree[N];
 19 Node :: Node(){
 20     fa=ch[0]=ch[1]=null;
 21     sum=now=times=1;id=plus=0;
 22 }
 23 void Plus(Node *x,int val){
 24     (x->plus+=val)%=mod;
 25     (x->sum+=val*x->size)%=mod;
 26     (x->now+=val)%=mod;
 27 }
 28 inline void Times(Node *x,int val){
 29     (x->times*=val)%=mod;
 30     (x->sum*=val)%=mod;
 31     (x->now*=val)%=mod;
 32     (x->plus*=val)%=mod;
 33 }
 34 void Node :: pushdown(){
 35     if(rev){
 36         swap(ch[0],ch[1]);
 37         if(ch[0]!=null)ch[0]->rev^=1;
 38         if(ch[1]!=null)ch[1]->rev^=1;
 39         rev=0;
 40     }
 41     if(times!=1){
 42         Times(ch[0],times);
 43         Times(ch[1],times);
 44         times=1;
 45     }
 46     if(plus){
 47         Plus(ch[0], plus);
 48         Plus(ch[1], plus);
 49         plus=0;
 50     }
 51     
 52 }
 53 void Node :: pushup(){
 54     sum=(ch[0]->sum+ch[1]->sum+now)%mod;
 55     size=ch[0]->size+ch[1]->size+1;
 56 }
 57 bool isroot(Node *x){
 58     return (x->fa->ch[0]!=x)&&(x->fa->ch[1]!=x);
 59 }
 60 void rotate(Node *x){
 61     Node *y=x->fa,*z=y->fa;
 62     int w=(y->ch[0]==x);
 63     x->ch[w]->fa=y;y->ch[w^1]=x->ch[w];
 64     y->fa=x;x->ch[w]=y;
 65     if(z->ch[0]==y)z->ch[0]=x;
 66     if(z->ch[1]==y)z->ch[1]=x;
 67     x->fa=z;
 68     y->pushup();x->pushup();
 69 }
 70 void splay(Node *x){
 71     Node *y,*z;
 72     x->pushdown();
 73     while(!isroot(x)){
 74         y=x->fa;z=y->fa;
 75         z->pushdown();y->pushdown();x->pushdown();
 76         if(((z->ch[0]==y)&&(y->ch[0]==x))||((z->ch[1]==y)&&(y->ch[1]==x)))rotate(y);
 77         rotate(x);
 78     }
 79 }
 80 void access(Node *x){
 81     Node *y=null;
 82     x->pushdown();
 83     while(x!=null){
 84         splay(x);
 85         x->ch[1]=y;
 86         x->pushup();
 87         y=x;x=x->fa;
 88     }
 89 }
 90 void make_root(Node *x){
 91     access(x);
 92     splay(x);
 93     x->rev^=1;
 94 }
 95 void link(Node *x,Node *y){
 96     make_root(x);
 97     x->fa=y;
 98 }
 99 void cut(Node *x,Node *y){
100     make_root(x);
101     access(y);
102     splay(y);
103     x->fa=y->ch[0]=null;
104     y->pushup();
105 }
106 void query(Node *x,Node *y){
107     make_root(x);
108     access(y);
109     splay(x);
110     x->pushdown();
111     printf("%lld\n",x->sum %mod);
112 }
113 void make_plus(Node *x,Node *y,int z){
114     make_root(x);
115     access(y);
116     splay(y);
117     Plus(y,z);
118 }
119 void make_times(Node *x,Node *y,int z){
120     make_root(x);
121     access(y);
122     splay(y);
123     Times(y,z);
124 }
125 signed main(){
126     null->ch[0]=null->ch[1]=null->fa=null;
127     null->sum=null->plus=null->times=null->rev=null->size=0;
128     scanf("%lld%lld",&n,&m);
129     for(int i=1;i<=n;i++)tree[i].id=i;
130     for(int i=1,u,v;i<n;i++){
131         scanf("%lld%lld",&u,&v);
132         link(&tree[u],&tree[v]);
133     }
134     for(int i=1,u,v,x,y;i<=m;i++){
135         scanf("%s",ch);
136         if(ch[0]=='+'){
137             scanf("%lld%lld%lld",&u,&v,&x);
138             make_plus(&tree[u],&tree[v],x);
139         }
140         if(ch[0]=='-'){
141             scanf("%lld%lld%lld%lld",&u,&v,&x,&y);
142             cut(&tree[u],&tree[v]);
143             link(&tree[x],&tree[y]);
144         }
145         if(ch[0]=='*'){
146             scanf("%lld%lld%lld",&u,&v,&x);
147             make_times(&tree[u],&tree[v],x);
148         }
149         if(ch[0]=='/'){
150             scanf("%lld%lld",&u,&v);
151             query(&tree[u],&tree[v]);
152         }
153     }
154     return 0;
155 }
tree

 

posted @ 2017-12-20 21:13  Ren_Ivan  阅读(210)  评论(0编辑  收藏  举报