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 }
人生如梦亦如幻 朝如晨露暮如霞。