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 。
 
 
正解:树链剖分
解题报告:
  链剖裸题。
  但是我居然调试了很久!!!先是迷之RE,结果是细节问题。。。然后是迷之WA,结果是中间变量没开long long
  多么痛的领悟。。。
 
 
  1. //It is made by jump~
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <ctime>
  9. #include <vector>
  10. #include <queue>
  11. #include <map>
  12. #include <set>
  13. #ifdef WIN32
  14. #define OT "%I64d"
  15. #else
  16. #define OT "%lld"
  17. #endif
  18. using namespace std;
  19. typedef long long LL;
  20. const int MAXN = ;
  21. const int MAXM = ;
  22. int n,m;
  23. int ecnt,cnt;
  24. int first[MAXN],to[MAXM],next[MAXM],id[MAXN],pre[MAXN],last[MAXN],deep[MAXN],father[MAXN],size[MAXN],son[MAXN],top[MAXN];
  25. int num[MAXN];
  26. LL qx,qy;
  27. int ql,qr;
  28. LL ans;
  29.  
  30. struct node{
  31. LL add;
  32. LL val;
  33. }t[MAXN*];
  34.  
  35. inline int getint()
  36. {
  37. int w=,q=;
  38. char c=getchar();
  39. while((c<'' || c>'') && c!='-') c=getchar();
  40. if (c=='-') q=, c=getchar();
  41. while (c>='' && c<='') w=w*+c-'', c=getchar();
  42. return q ? -w : w;
  43. }
  44.  
  45. inline void dfs1(int x,int fa) {
  46. size[x] = ;
  47. for(int i = first[x];i;i = next[i]) {
  48. int v = to[i];
  49. if(v != fa){
  50. father[v] = x; deep[v] = deep[x]+;
  51. dfs1(v,x);
  52. size[x] += size[v]; if(size[v] > size[son[x]]) son[x] = v;
  53. }
  54. }
  55. }
  56.  
  57. inline void dfs2(int x,int fa){
  58. id[x] = ++cnt; pre[cnt]=x; if(son[x]!=) top[son[x]]=top[x],dfs2(son[x],x);
  59. for(int i = first[x];i;i = next[i]){
  60. int v = to[i];
  61. if(v != fa && v != son[x]) {
  62. top[v]=v;
  63. dfs2(v,x);
  64. }
  65. }
  66. last[x] = cnt;
  67. }
  68.  
  69. inline void build(int root,int l,int r){
  70. if(l == r) { t[root].val = num[pre[l]]; return ; }
  71. int mid = (l + r)/; int lc = root*,rc = lc+;
  72. build(lc,l,mid); build(rc,mid+,r);
  73. t[root].val = t[lc].val + t[rc].val;
  74. }
  75.  
  76. inline void update(int root,int l,int r){
  77. if(ql <= l && qr >= r) { t[root].add += qy; t[root].val += qy*(r-l+); }
  78. else{
  79. int mid = (l + r)/;
  80. int lc = root*,rc = lc + ;
  81. if(ql <= mid) update(lc,l,mid); if(qr > mid) update(rc,mid+,r);
  82. t[root].val = t[lc].val + t[rc].val;
  83. t[root].val += t[root].add*(r-l+);
  84. }
  85. }
  86.  
  87. inline void query(int root,int l,int r,LL lei){
  88. if(ql <= l && qr >= r) {
  89. ans += t[root].val;
  90. ans += (LL)lei*(LL)(r-l+);
  91. return ;
  92. }
  93. int mid = (l+r)/; int lc = root*,rc = lc+;
  94. if(ql <= mid) query(lc,l,mid,lei+t[root].add); if(qr > mid) query(rc,mid+,r,lei+t[root].add);
  95. }
  96.  
  97. inline void work(int x){
  98. ans=;
  99. int f1 = top[x];
  100. while(f1!=) {
  101. ql=id[f1]; qr=id[x];
  102. query(,,n,);
  103. x=father[f1]; f1=top[x];
  104. }
  105. ql=; qr=id[x]; query(,,n,);
  106. printf(OT"\n",ans);
  107. }
  108.  
  109. inline void solve(){
  110. n = getint(); m = getint();
  111. for(int i=;i<=n;i++) num[i] = getint();
  112. int x,y;
  113. for(int i = ;i < n;i++) {
  114. x = getint(); y = getint();
  115. next[++ecnt] = first[x]; first[x] = ecnt; to[ecnt] = y;
  116. next[++ecnt] = first[y]; first[y] = ecnt; to[ecnt] = x;
  117. }
  118.  
  119. deep[]=; dfs1(,);
  120. top[]=; dfs2(,);
  121. build(,,n);
  122. int ljh;
  123. for(int i = ;i <= m;i++) {
  124. ljh = getint();
  125. if(ljh == ){
  126. qx = id[getint()]; qy = getint();
  127. ql=qx; qr=qx;
  128. update(,,n);
  129. }
  130. else if(ljh == ){
  131. x = getint(); qy = getint();
  132. qr = last[x]; ql = id[x];
  133. update(,,n);
  134. }
  135. else{
  136. qx=getint(); work(qx);
  137. }
  138. }
  139. }
  140.  
  141. int main()
  142. {
  143. solve();
  144. return ;
  145. }

BZOJ4034 T2的更多相关文章

  1. bzoj4034: [HAOI2015]T2

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2684  Solved: 843 Description 有一 ...

  2. 【BZOJ4034】T2(树链剖分)

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

  3. BZOJ4034——[HAOI2015]T2

    1.题目大意:用一个数据结构支持树的点修改和子树修改.树上路径和 2.分析:树链剖分裸题 #include <cstdio> #include <cstdlib> #inclu ...

  4. [BZOJ4034] [HAOI2015] T2 (树链剖分)

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

  5. 【DFS序】【线段树】bzoj4034 [HAOI2015]T2

    分开维护树的入栈序和出栈序,用两棵线段树.回答时就是用一颗的减去另一棵的. #include<cstdio> #include<algorithm> using namespa ...

  6. 【bzoj4034】[HAOI2015]T2

    siz[v]表示以v为根的子树的节点数 top[v]表示v所在的重链的顶端节点 fa[v]表示v的父亲 pos[v]表示v的父边标号 mx[v]表示v的子树中边的标号最大的那条边 参考:http:// ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. [Noip2016]蚯蚓 D2 T2 队列

    [Noip2016]蚯蚓 D2 T2 Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯 ...

  9. T2 Func<in T1,out T2>(T1 arg)

    委托调用方法的4种方式. using System; using System.Collections.Generic; namespace ConsoleApplication1 { delegat ...

随机推荐

  1. HUDSON(Java开发的一种持续集成工具)

    Hudson是Jenkins的前身,是基于Java开发的一种持续集成工具,用于监控程序重复的工作,包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作. Hudson的特性 1.易于 ...

  2. 转:CentOS设置时区

    from: http://os.51cto.com/art/201004/192805.htm 建议直接使用: 1. session 临时修改查看: tzselect. 然后数字键入,回车 2. 永久 ...

  3. 解决Gradle DSL method not found: ‘android()’

    最近导入as的项目出了这样的问题 这个问题困扰了我很长时间,好吧,搜了半天全都是runProguard的,最后在stackoverflow上搜到解决办法了: http://stackoverflow. ...

  4. 【转】MySQL 性能优化的最佳20多条经验分享

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.   当我们去设计数据库表结构,对操 ...

  5. sed 4个功能

    [root@lanny test]# cat test.txt test liyao lanny 经典博文: http://oldboy.blog.51cto.com/2561410/949365 h ...

  6. Linux 守护进程二(激活守护进程)

    //守护进程--读文件 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

  7. Gruntjs: task之文件映射

    由于大多数的任务执行文件操作,Grunt提供了一个强大的抽象声明说明任务应该操作哪些文件.这里总结了几种src-dest(源文件-目标文件)文件映射的方式,提供了不同程度的描述和控制操作方式. 1. ...

  8. 记录毕业论文 LanguageTool 二次开发时用到的网站

    LanguageTool Development LanguageTool Supported Languages Share your knowledge about LT - LanguageTo ...

  9. [转]MySQL Explain详解

    在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有 ...

  10. 【WEB前端经验之谈】时间一年半,或沉淀、或从零开始。

    距上次写博客还是有点久了,中间有个写的念头,不过由于不知道写什么也就放弃了. 14年4月份第一份前端工作到现在也有一年半之久了,自己对前端的热爱相对于一年前是有过之而无不及.一年半的时间里自己也成长了 ...