Description

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

Input

第一行包含两个整数 N, M 。表示点数和操作数。接下来一行 N 个整数,表示树中节点的初始权值。接下来 N-1 
行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。再接下来 M 行,每行分别表示一次操作。其中
第一个数表示该操作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。

Output

对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

Sample Input

5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3

Sample Output

6
9
13

HINT

对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不会超过 10^6 。

一道裸的树剖却因为建树时候的sb错误搞了半天
不想说什么(不过这个题好像会炸int)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define LL long long
  5. #define MAXN (100000+50)
  6. using namespace std;
  7. LL Tree[MAXN];
  8. LL T_num[MAXN];
  9. LL Depth[MAXN];
  10. LL Father[MAXN];
  11. LL Sum[MAXN];
  12. LL Son[MAXN];
  13. LL Top[MAXN];
  14. LL a[MAXN];
  15. LL n,m,u,v,sum;
  16. LL head[MAXN],num_edge;
  17. struct node1
  18. {
  19. LL val;
  20. LL add;
  21. } Segt[MAXN*];
  22. struct node2
  23. {
  24. LL to;
  25. LL next;
  26. } edge[MAXN*];
  27. void add(LL u,LL v)
  28. {
  29. edge[++num_edge].to=v;
  30. edge[num_edge].next=head[u];
  31. head[u]=num_edge;
  32. }
  33.  
  34. void Dfs1(LL x)
  35. {
  36. Sum[x]=;
  37. Depth[x]=Depth[Father[x]]+;
  38. for (LL i=head[x]; i!=; i=edge[i].next)
  39. if (edge[i].to!=Father[x])
  40. {
  41. Father[edge[i].to]=x;
  42. Dfs1(edge[i].to);
  43. Sum[x]+=Sum[edge[i].to];
  44. if (Son[x]== || (Sum[Son[x]]<Sum[edge[i].to]))
  45. Son[x]=edge[i].to;
  46. }
  47. }
  48.  
  49. void Dfs2(LL x,LL tp)
  50. {
  51. T_num[x]=++sum;
  52. Tree[sum]=a[x];
  53. Top[x]=tp;
  54. if (Son[x])
  55. Dfs2(Son[x],tp);
  56. for (LL i=head[x]; i!=; i=edge[i].next)
  57. if (edge[i].to!=Son[x] && edge[i].to!=Father[x])
  58. Dfs2(edge[i].to,edge[i].to);
  59. }
  60.  
  61. void Pushdown(LL node,LL l,LL r)
  62. {
  63. if (Segt[node].add!=)
  64. {
  65. LL mid=(l+r)/;
  66. Segt[node*].val+=Segt[node].add*(mid-l+);
  67. Segt[node*+].val+=Segt[node].add*(r-mid);
  68. Segt[node*].add+=Segt[node].add;
  69. Segt[node*+].add+=Segt[node].add;
  70. Segt[node].add=;
  71. }
  72. }
  73.  
  74. void Build(LL node,LL l,LL r)
  75. {
  76. if (l==r)
  77. Segt[node].val=Tree[l];
  78. else
  79. {
  80. LL mid=(l+r)/;
  81. Build(node*,l,mid);
  82. Build(node*+,mid+,r);
  83. Segt[node].val=Segt[node*].val+Segt[node*+].val;
  84. }
  85. }
  86.  
  87. void Update(LL node,LL l,LL r,LL l1,LL r1,LL k)
  88. {
  89. if (l>r1 || r<l1)
  90. return;
  91. if (l1<=l && r<=r1)
  92. {
  93. Segt[node].val+=(r-l+)*k;
  94. Segt[node].add+=k;
  95. return;
  96. }
  97. Pushdown(node,l,r);
  98. LL mid=(l+r)/;
  99. Update(node*,l,mid,l1,r1,k);
  100. Update(node*+,mid+,r,l1,r1,k);
  101. Segt[node].val=Segt[node*].val+Segt[node*+].val;
  102. }
  103.  
  104. LL Query(LL node,LL l,LL r,LL l1,LL r1)
  105. {
  106. if (l>r1 || r<l1)
  107. return ;
  108. if (l1<=l && r<=r1)
  109. return Segt[node].val;
  110. Pushdown(node,l,r);
  111. LL mid=(l+r)/;
  112. return Query(node*,l,mid,l1,r1)+Query(node*+,mid+,r,l1,r1);
  113. }
  114.  
  115. LL Get(LL x)
  116. {
  117. LL ans=;
  118. while (x!=)
  119. {
  120. ans+=Query(,,n,T_num[Top[x]],T_num[x]);
  121. x=Father[Top[x]];
  122. }
  123. return ans;
  124. }
  125.  
  126. int main()
  127. {
  128. scanf("%lld%lld",&n,&m);
  129. for (LL i=; i<=n; ++i)
  130. scanf("%lld",&a[i]);
  131. for (LL i=; i<=n-; ++i)
  132. {
  133. scanf("%lld%lld",&u,&v);
  134. add(u,v);
  135. add(v,u);
  136. }
  137. Dfs1();
  138. Dfs2(,);
  139. Build(,,n);
  140. for (LL i=; i<=m; ++i)
  141. {
  142. LL p,x,y;
  143. scanf("%lld",&p);
  144. if (p==)
  145. {
  146. scanf("%lld%lld",&x,&y);
  147. Update(,,n,T_num[x],T_num[x],y);
  148. }
  149. if (p==)
  150. {
  151. scanf("%lld%lld",&x,&y);
  152. Update(,,n,T_num[x],T_num[x]+Sum[x]-,y);
  153. }
  154. if (p==)
  155. {
  156. scanf("%lld",&x);
  157. printf("%lld\n",Get(x));
  158. }
  159. }
  160. }

4034. [HAOI2015]树上操作【树链剖分】的更多相关文章

  1. bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4352  Solved: 1387[Submit][Stat ...

  2. bzoj 4034: [HAOI2015]树上操作——树链剖分

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...

  3. BZOJ 4034[HAOI2015]树上操作(树链剖分)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...

  4. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

  5. 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树

    [BZOJ4034][HAOI2015]树上操作 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 ...

  6. BZOJ4034 [HAOI2015]树上操作 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...

  7. P3178 [HAOI2015]树上操作 树链剖分

    这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇. 题干: 题目描述 有一棵点数为 N 的树,以点 为根,且树点有边权.然后有 M 个操作, ...

  8. BZOJ4034[HAOI2015]树上操作——树链剖分+线段树

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...

  9. bzoj4034 [HAOI2015]树上操作——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034 树剖裸题: 一定要注意 long long !!! update 的时候别忘了 pus ...

  10. [HAOI2015]树上操作-树链剖分

    #include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; #define mid ((l+r)>> ...

随机推荐

  1. MSSQL存储过程实现拼接sql的注意点

    这里我昨天碰到的问题就是执行一段根据变量tableName对不同的表进行字段状态的更改.由于服务器原因,我不能直接在数据访问层写SQL,所以只好抽离出来放到存储过程里面. 这里就出现了一个问题,我花费 ...

  2. [C语言] 数据结构-逻辑结构和物理结构

    数据结构:相互之间存在一种或多种特定关系的数据元素的集合 1.数据结构分为逻辑结构和物理结构 集合结构:集合结构中的数据元素除了同属于一个集合外,他们之间没有其他关系 线性结构:线性结构中的数据元素之 ...

  3. 利用CEF山寨一个翻译器

    起因 在某些情况下,有将从某种类型的语言翻译成另一种类型语言的需求.比如在生成实体时,可能需要将中文名称转换成英文.于是利用CEFSharp山寨了一个翻译器.效果图如下: CEF简介 CEF全称为Ch ...

  4. 使用tcmalloc替换系统的malloc

    https://blog.csdn.net/educast/article/details/79166553?utm_source=blogxgwz0 今天对服务器进行压测,模拟的请求量到4万次/分的 ...

  5. Effective C++ Placement new

    #include <iostream> #include <cstdlib> using namespace std; class Card { private: int m_ ...

  6. 基于Vue实现图片在指定区域内移动

    当图片比要显示的区域大时,需要将多余的部分隐藏掉,我们可以通过绝对定位来实现,并通过动态修改图片的left值和top值从而实现图片的移动.具体实现效果如下图,如果我们移动的是div 实现思路相仿. 此 ...

  7. javascript数组元素全排列

    多个数组(数量不定)例如三个数组 {a,b} {1,2} {d}排列组合后为a,1,da,2,db,1,db,2,d是js的算法哦 var arr = [["a","b& ...

  8. Laravel 支付宝异步通知 419报错

    支付宝在支付是有服务器通知和网页通知,一个在前端展示,一个在后台操作, laravel框架自带csrf_token验证. 所以我们需要把支付的路由跳过验证 可以在中间键的csrf配置中更改

  9. Android EditText方框验证码 短信验证码攻略

    本文由xiawe_i提供. xiawe_i的博客地址是: http://www.jianshu.com/u/fa9f03a240c6 项目中有这样一个需求: 验证码页是四个方框,输入验证码方框颜色改变 ...

  10. Android 后台线程,timertask实现定期更新时间

    简述:这是一类定时功能的原型,用来在后台线程中运行一些定时的服务,比如定时修改时间 知识点: 1. Android多线程的消息通信(handler) 2. Java中时间的获取,以及String的格式 ...