记录编号 248006 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]tree(伍一鸣) 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 14.977 s
提交时间 2016-04-09 21:50:24 内存使用 3.56 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cmath>
  4. using namespace std;
  5. const int SIZEN=100010,MOD=51061;
  6. typedef long long LL;
  7. int N,M;
  8. class miku
  9. {
  10. public:
  11. int son[2],fa;
  12. unsigned int sum,val,add,mul,siz;
  13. bool rev;
  14. miku()
  15. {
  16. fa=son[0]=son[1]=0;
  17. val=sum=mul=siz=1;add=0;
  18. }
  19. #define sum(x) tr[x].sum
  20. #define val(x) tr[x].val
  21. #define mul(x) tr[x].mul
  22. #define siz(x) tr[x].siz
  23. #define rev(x) tr[x].rev
  24. #define add(x) tr[x].add
  25. #define fa(x) tr[x].fa
  26. #define ls(x) tr[x].son[0]
  27. #define rs(x) tr[x].son[1]
  28. }tr[SIZEN];
  29. void update(int x)
  30. {
  31. if(!x) return;
  32. sum(x)=(sum(ls(x))+sum(rs(x))+val(x))%MOD;
  33. siz(x)=siz(ls(x))+siz(rs(x))+1;
  34. }
  35. void Node_mul(int x,int t)
  36. {
  37. if(!x) return;
  38. sum(x)=(sum(x)*t)%MOD;
  39. add(x)=(add(x)*t)%MOD;
  40. val(x)=(val(x)*t)%MOD;
  41. mul(x)=(mul(x)*t)%MOD;
  42. }
  43. void Node_add(int x,int t)
  44. {
  45. if(!x) return;
  46. sum(x)=(sum(x)+t*siz(x))%MOD;
  47. val(x)=(val(x)+t)%MOD;
  48. add(x)=(add(x)+t)%MOD;
  49. }
  50. void pushdown(int x)
  51. {
  52. if(mul(x)!=1)
  53. {
  54. Node_mul(ls(x),mul(x));
  55. Node_mul(rs(x),mul(x));
  56. mul(x)=1;
  57. }
  58. if(add(x)!=0)
  59. {
  60. Node_add(ls(x),add(x));
  61. Node_add(rs(x),add(x));
  62. add(x)=0;
  63. }
  64. if(rev(x))
  65. {
  66. rev(x)^=1;
  67. swap(ls(x),rs(x));
  68. if(ls(x)) rev(ls(x))^=1;
  69. if(rs(x)) rev(rs(x))^=1;
  70. }
  71. }
  72. bool isroot(int x)
  73. {
  74. if(fa(x)==0) return 1;
  75. if(ls(fa(x))==x||rs(fa(x))==x) return 0;
  76. return 1;
  77. }
  78. void rotate(int x)
  79. {
  80. int y=tr[x].fa,z=tr[y].fa,l,r;
  81. if(tr[y].son[0]==x) l=0;
  82. else l=1;
  83. r=l^1;
  84. if(!isroot(y))
  85. {
  86. if(tr[z].son[0]==y) tr[z].son[0]=x;
  87. else tr[z].son[1]=x;
  88. }
  89. tr[tr[x].son[r]].fa=y;tr[x].fa=z;tr[y].fa=x;
  90. tr[y].son[l]=tr[x].son[r];tr[x].son[r]=y;
  91. update(y);update(x);
  92. }
  93. void splay(int x)
  94. {
  95. pushdown(x);
  96. while(!isroot(x))
  97. {
  98. int y=fa(x),z=fa(y);
  99. pushdown(z);pushdown(y);pushdown(x);
  100. if(!isroot(y))
  101. {
  102. if((tr[y].son[0]==x)^(tr[z].son[0]==y)) rotate(x);
  103. else rotate(y);
  104. }
  105. rotate(x);
  106. }
  107. }
  108. void access(int x)
  109. {
  110. int v=0;
  111. while(x)
  112. {
  113. splay(x);
  114. tr[x].son[1]=v;
  115. update(x);
  116. v=x;
  117. x=tr[x].fa;
  118. }
  119. }
  120. void make_root(int x)
  121. {
  122. access(x);
  123. splay(x);
  124. tr[x].rev^=1;
  125. }
  126. void link(int u,int v)
  127. {
  128. make_root(v);
  129. //splay(v);
  130. fa(v)=u;
  131. }
  132. void read()
  133. {
  134. scanf("%d%d",&N,&M);
  135. int fr,to;
  136. for(int i=1;i<N;i++)
  137. {
  138. scanf("%d%d",&fr,&to);
  139. link(fr,to);
  140. }
  141. }
  142. void Path_mul(int x,int y,int t)
  143. {
  144. make_root(x);
  145. access(y);
  146. splay(y);
  147. Node_mul(y,t);
  148. }
  149. void Path_add(int x,int y,int t)
  150. {
  151. make_root(x);
  152. access(y);
  153. splay(y);
  154. Node_add(y,t);
  155. }
  156. void cut(int x,int y)
  157. {
  158. make_root(x);
  159. access(y);
  160. splay(x);
  161. rs(x)=0;fa(y)=0;
  162. update(x);
  163. }
  164. int query(int x,int y)
  165. {
  166. make_root(x);
  167. access(y);
  168. splay(y);
  169. return sum(y);
  170. }
  171. void work()
  172. {
  173. char c;
  174. int fr,to,w;
  175. int u,v;
  176. for(int i=1;i<=M;i++)
  177. {
  178. while(true)
  179. {
  180. c=getchar();
  181. if(c!='\n'&&c!='\r') break;
  182. }
  183. //cout<<c<<endl;
  184. if(c=='*')
  185. {
  186. scanf("%d%d%d",&fr,&to,&w);
  187. Path_mul(fr,to,w);
  188. }
  189. if(c=='/')
  190. {
  191. scanf("%d%d",&fr,&to);
  192. int ans=query(fr,to);
  193. printf("%d\n",ans);
  194. }
  195. if(c=='+')
  196. {
  197. scanf("%d%d%d",&fr,&to,&w);
  198. Path_add(fr,to,w);
  199. }
  200. if(c=='-')
  201. {
  202. scanf("%d%d%d%d",&fr,&to,&u,&v);
  203. cut(fr,to);
  204. link(u,v);
  205. }
  206. }
  207. }
  208. int main()
  209. {
  210. freopen("nt2012_wym_tree.in","r",stdin);
  211. freopen("nt2012_wym_tree.out","w",stdout);
  212. tr[0].val=tr[0].sum=tr[0].add=tr[0].siz=0;
  213. read();
  214. work();
  215. return 0;
  216. }