记录编号 143521 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]tree(伍一鸣) 最终得分 100
用户昵称 GravatarChenyao2333 是否通过 通过
代码语言 C++ 运行时间 13.623 s
提交时间 2014-12-15 17:12:21 内存使用 5.65 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<vector>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<set>
  7. #include<queue>
  8. #include<stack>
  9. #include<map>
  10. #include<cmath>
  11. #define CL(x) memset(x,0,sizeof(x))
  12. #define rep(i,s,t) for(int i=(s);i<=(t);i++)
  13. #define dow(i,s,t) for(int i=(s);i>=(t);i--)
  14. using namespace std;
  15. typedef long long LL;
  16. LL read(){
  17. LL ret=0,f=1;
  18. char x=getchar();
  19. while(!(x>='0' && x<='9')){if(x=='-')f=-1;x=getchar();}
  20. while(x>='0' && x<='9') ret=ret*10+x-'0', x=getchar();
  21. return ret*f;
  22. }
  23. char get_char(){
  24. char x=getchar();
  25. while(!(x=='+' || x=='-' || x=='*' || x=='/')) x=getchar();
  26. return x;
  27. }
  28.  
  29. const int MAXN=1e5+10;
  30. const int MOD=51061;
  31.  
  32. struct node{
  33. int ls,rs,fa;
  34. LL sz,val,sum,mul,add;
  35. bool revc;
  36. node(){ val=sum=mul=sz=1; }
  37. }t[MAXN];
  38. void push_up(int n){
  39. if(!n) return;
  40. t[n].sum=(t[t[n].ls].sum+t[t[n].rs].sum+t[n].val)%MOD;
  41. t[n].sz=t[t[n].ls].sz+t[t[n].rs].sz+1;
  42. }
  43. void node_mul(int n,int val){
  44. if(!n) return;
  45. t[n].val=(t[n].val*val)%MOD;
  46. t[n].sum=(t[n].sum*val)%MOD;
  47. t[n].mul=(t[n].mul*val)%MOD;
  48. t[n].add=(t[n].add*val)%MOD;
  49. }
  50. void node_add(int n,int val){
  51. if(!n) return;
  52. t[n].val=(t[n].val+val)%MOD;
  53. t[n].sum=(t[n].sum+val*t[n].sz)%MOD;
  54. t[n].add=(t[n].add+val)%MOD;
  55. }
  56. void push_down(int n){
  57. if(t[n].mul!=1){
  58. node_mul(t[n].ls,t[n].mul);
  59. node_mul(t[n].rs,t[n].mul);
  60. t[n].mul=1;
  61. }
  62. if(t[n].add){
  63. node_add(t[n].ls,t[n].add);
  64. node_add(t[n].rs,t[n].add);
  65. t[n].add=0;
  66. }
  67. if(t[n].revc){
  68. swap(t[n].ls,t[n].rs);
  69. if(t[n].ls) t[t[n].ls].revc^=1;
  70. if(t[n].rs) t[t[n].rs].revc^=1;
  71. t[n].revc^=1;
  72. }
  73. }
  74. void zig(int x){
  75. int y=t[x].fa, z=t[y].fa;
  76. if(t[z].ls==y) t[z].ls=x;
  77. if(t[z].rs==y) t[z].rs=x;
  78. t[x].fa=z;
  79. t[y].ls=t[x].rs, t[t[x].rs].fa=y;
  80. t[x].rs=y, t[y].fa=x;
  81. push_up(y), push_up(x);
  82. }
  83. void zag(int x){
  84. int y=t[x].fa, z=t[y].fa;
  85. if(t[z].ls==y) t[z].ls=x;
  86. if(t[z].rs==y) t[z].rs=x;
  87. t[x].fa=z;
  88. t[y].rs=t[x].ls, t[t[x].ls].fa=y;
  89. t[x].ls=y, t[y].fa=x;
  90. push_up(y), push_up(x);
  91. }
  92. bool is_root(int x){
  93. int f=t[x].fa;
  94. return t[f].ls!=x && t[f].rs!=x;
  95. }
  96. void splay(int n){
  97. int x=n;
  98. push_down(x);
  99. while(!is_root(x)){
  100. int y=t[x].fa, z=t[y].fa;
  101. push_down(z), push_down(y), push_down(x);
  102. if(is_root(y)){
  103. if(t[y].ls==x) zig(x);
  104. else zag(x);
  105. break;
  106. }else if(t[z].ls==y){
  107. if(t[y].ls==x) zig(y), zig(x);
  108. else zag(x), zig(x);
  109. }else{
  110. if(t[y].rs==x) zag(y), zag(x);
  111. else zig(x), zag(x);
  112. }
  113. }
  114. }
  115. void access(int x){
  116. int y=0;
  117. while(x){
  118. splay(x);
  119. t[x].rs=y;
  120. push_up(x);
  121. y=x;
  122. x=t[x].fa;
  123. }
  124. }
  125. void make_root(int x){
  126. access(x);
  127. splay(x);
  128. t[x].revc^=1;
  129. }
  130. void link(int u,int v){
  131. make_root(v);
  132. splay(v);
  133. t[v].fa=u;
  134. }
  135. void cut(int u,int v){
  136. make_root(u);
  137. access(v);
  138. splay(u);
  139. t[u].rs=0;
  140. t[v].fa=0;
  141. push_up(u);
  142. }
  143. void add(int u,int v,int c){
  144. make_root(u);
  145. access(v);
  146. splay(v);
  147. node_add(v,c);
  148. }
  149. void mul(int u,int v,int c){
  150. make_root(u);
  151. access(v);
  152. splay(v);
  153. node_mul(v,c);
  154. }
  155. int query(int u,int v){
  156. make_root(u);
  157. access(v);
  158. splay(v);
  159. return t[v].sum;
  160. }
  161.  
  162. int N,Q;
  163. int main(){
  164. //freopen("in.txt","r",stdin);
  165. //freopen("1.out","w",stdout);
  166. freopen("nt2012_wym_tree.in","r",stdin);
  167. freopen("nt2012_wym_tree.out","w",stdout);
  168. t[0].val=t[0].sum=t[0].mul=t[0].sz=0;
  169. N=read(), Q=read();
  170. rep(i,1,N-1){
  171. int u=read(), v=read();
  172. link(u,v);
  173. }
  174. rep(i,1,Q){
  175. char op=get_char();
  176. if(op=='+'){
  177. int u=read(), v=read(), c=read();
  178. add(u,v,c);
  179. }else if(op=='-'){
  180. int u1=read(), v1=read(), u2=read(), v2=read();
  181. cut(u1,v1);
  182. link(u2,v2);
  183. }else if(op=='*'){
  184. int u=read(), v=read(), c=read();
  185. mul(u,v,c);
  186. }else{
  187. int u=read(), v=read();
  188. printf("%d\n",query(u,v));
  189. }
  190. }
  191. return 0;
  192. }