记录编号 413535 评测结果 AAAAAAAAAA
题目名称 [HAOI 2015]树上操作 最终得分 100
用户昵称 GravatarHzoi_Maple 是否通过 通过
代码语言 C++ 运行时间 0.862 s
提交时间 2017-06-11 18:28:08 内存使用 13.67 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. using namespace std;
  5. #define ll long long
  6. int n,m,x,y,z,w[200001];
  7. int adj[200001],num;
  8. ll add[400001],zh[400001];
  9. struct kk
  10. {
  11. int s,t,next;
  12. }k[200001];
  13. void swap(ll &a,ll &b){
  14. ll c=a;
  15. a=b;
  16. b=c;
  17. }
  18. inline int read(){
  19. int zh=0,f=1;
  20. char ch=getchar();
  21. while(ch<'0'||ch>'9'){
  22. if(ch=='-')
  23. f=-1;
  24. ch=getchar();
  25. }
  26. while(ch>='0'&&ch<='9'){
  27. zh=zh*10+ch-'0';
  28. ch=getchar();
  29. }
  30. return zh*f;
  31. }
  32. inline void pushup(int i)
  33. {
  34. zh[i]=zh[i<<1]+zh[i<<1|1];
  35. }
  36. void init(int x,int y){
  37. k[num].s=x;
  38. k[num].t=y;
  39. k[num].next=adj[x];
  40. adj[x]=num++;
  41. }
  42. int fa[100001],dp[100001],son[100001],size[100001];
  43. void Dfs1(int x,int father,int dep){
  44. fa[x]=father;dp[x]=dep;
  45. size[x]=1;son[x]=0;
  46. for(int i=adj[x];i!=-1;i=k[i].next){
  47. int o=k[i].t;
  48. if(o!=father){
  49. Dfs1(o,x,dep+1);
  50. size[x]+=size[o];
  51. if(size[son[x]]<size[o])
  52. son[x]=o;
  53. }
  54. }
  55. }
  56. int top[100001],id[100001],cnt,pos[100001];
  57. int wcx[100001],yl[100001];//记得某皮说过:只可意会不可言传~
  58. void Dfs2(int u,int tp){
  59. top[u]=tp;id[u]=++cnt;
  60. pos[cnt]=u;wcx[u]=cnt;
  61. if(son[u])
  62. Dfs2(son[u],tp);
  63. for(int i=adj[u];i!=-1;i=k[i].next){
  64. int o=k[i].t;
  65. if(o!=fa[u]&&o!=son[u]){
  66. Dfs2(o,o);
  67. }
  68. }
  69. yl[u]=cnt;
  70. }
  71. void build(int l,int r,int x){
  72. add[x]=0;
  73. if(l==r){
  74. zh[x]=w[pos[l]];
  75. return;
  76. }
  77. int mid=(l+r)>>1;
  78. build(l,mid,x<<1);
  79. build(mid+1,r,x<<1|1);
  80. zh[x]=zh[x<<1]+zh[x<<1|1];
  81. }
  82. void pushd(int x,int len){
  83. if(add[x]){
  84. add[x<<1]+=add[x];
  85. add[x<<1|1]+=add[x];
  86. zh[x<<1]+=add[x]*(len-(len>>1));
  87. zh[x<<1|1]+=add[x]*(len>>1);
  88. add[x]=0;
  89. }
  90. }
  91. void update(int L,int R,ll c,int l,int r,int rt)
  92. {
  93. if(L<=l&&r<=R)
  94. {
  95. add[rt]+=c;
  96. zh[rt]+=(ll)c*(r-l+1);
  97. return;
  98. }
  99. pushd(rt,r-l+1);
  100. int mid=(l+r)>>1;
  101. if(L<=mid)
  102. update(L,R,c,l,mid,2*rt);
  103. if(mid<R)
  104. update(L,R,c,mid+1,r,2*rt+1);
  105. pushup(rt);
  106. }
  107. ll ask(int s,int t,int l,int r,int x){
  108. if(s<=l&&t>=r) return zh[x];
  109. pushd(x,r-l+1);
  110. int mid=(l+r)>>1;ll ans=0;
  111. if(s<=mid) ans+=ask(s,t,l,mid,2*x);
  112. if(t>mid) ans+=ask(s,t,mid+1,r,2*x+1);
  113. return ans;
  114. }
  115. ll query(int x,int y){
  116. int fx=top[x],fy=top[y];
  117. ll res=0;
  118. while(fx^fy){
  119. if(dp[fx]<dp[fy]){
  120. swap(x,y);
  121. swap(fx,fy);
  122. }
  123. res+=ask(id[fx],id[x],1,n,1);
  124. x=fa[fx];fx=top[x];
  125. }
  126. if(dp[x]>dp[y]) swap(x,y);
  127. res+=ask(id[x],id[y],1,n,1);
  128. return res;
  129. }
  130. int main()
  131. {
  132. freopen("haoi2015_t2.in","r",stdin);
  133. freopen("haoi2015_t2.out","w",stdout);
  134. memset(adj,-1,sizeof(adj));
  135. n=read();m=read();
  136. for(int i=1;i<=n;++i)
  137. w[i]=read();
  138. for(int i=1;i<n;++i){
  139. x=read();y=read();
  140. init(x,y);
  141. init(y,x);
  142. }
  143. Dfs1(1,0,0);
  144. Dfs2(1,1);
  145. build(1,n,1);
  146. for(int i=1;i<=m;++i){
  147. x=read();
  148. if(x==1){
  149. y=read();z=read();
  150. update(wcx[y],wcx[y],z,1,n,1);
  151. }
  152. if(x==2){
  153. y=read();z=read();
  154. update(wcx[y],yl[y],z,1,n,1);
  155. }
  156. if(x==3){
  157. y=read();
  158. printf("%lld\n",query(1,y));
  159. }
  160. }
  161. // while(1);
  162. return 0;
  163. }