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 。
  

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 using namespace std;
  6 const int maxn=100010;
  7 int cnt,fir[maxn],to[maxn<<1],nxt[maxn<<1],n,m;
  8 void addedge(int a,int b){
  9     nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;
 10 }
 11 long long key[maxn],tr[maxn<<2],add[maxn<<2];
 12 int ID[maxn],fa[maxn],top[maxn],end[maxn],sz[maxn],son[maxn];
 13 void Push_up(int x){
 14     tr[x]=tr[x<<1]+tr[x<<1|1];
 15 }
 16 void Add(int x,int l,int r,long long d){
 17     tr[x]+=(r-l+1)*d;
 18     add[x]+=d;
 19 }
 20 void Push_down(int x,int l,int r){
 21     if(add[x]){
 22         int mid=(l+r)>>1;
 23         Add(x<<1,l,mid,add[x]);
 24         Add(x<<1|1,mid+1,r,add[x]);
 25         add[x]=0;
 26     }
 27 }
 28 void Updata(int node,int l,int r,int a,int b,long long d){
 29     if(l>=a&&r<=b){
 30         Add(node,l,r,d);
 31         return;
 32     }
 33     Push_down(node,l,r);
 34     int mid=(l+r)>>1;
 35     if(mid>=a)Updata(node<<1,l,mid,a,b,d);
 36     if(mid<b) Updata(node<<1|1,mid+1,r,a,b,d);
 37     Push_up(node);
 38 }
 39 long long Query(int node,int l,int r,int a,int b){
 40     if(l>=a&&r<=b)return tr[node];
 41     Push_down(node,l,r);
 42     int mid=(l+r)>>1;
 43     long long ret=0;
 44     if(mid>=a)ret=Query(node<<1,l,mid,a,b);
 45     if(mid<b) ret+=Query(node<<1|1,mid+1,r,a,b);
 46     return ret;
 47 }
 48 void DFS(int x){
 49     sz[x]=1;
 50     for(int i=fir[x];i;i=nxt[i]){
 51         if(to[i]==fa[x])continue;
 52         fa[to[i]]=x;
 53         DFS(to[i]);
 54         sz[x]+=sz[to[i]];
 55         son[x]=sz[son[x]]<sz[to[i]]?to[i]:son[x];
 56     }
 57 }
 58 long long Solve(int y){
 59     long long ret=0;
 60     while(y){
 61         ret+=Query(1,1,n,ID[top[y]],ID[y]);
 62         y=fa[top[y]];
 63     }
 64     return ret;
 65 }
 66 int cont;
 67 void DFS2(int x,int tp){
 68     ID[x]=++cont;top[x]=tp;
 69     if(son[x])DFS2(son[x],tp);
 70     for(int i=fir[x];i;i=nxt[i])
 71         if(to[i]!=fa[x]&&to[i]!=son[x])
 72             DFS2(to[i],to[i]);
 73     end[x]=cont;
 74 }
 75 int main(){
 76     freopen("t2.in","r",stdin);
 77     freopen("t2.out","w",stdout);
 78     scanf("%d %d",&n,&m);
 79     for(int i=1;i<=n;i++)
 80         scanf("%lld",&key[i]);
 81
 82     for(int i=1,a,b;i<n;i++){
 83         scanf("%d %d",&a,&b);
 84         addedge(a,b);
 85         addedge(b,a);
 86     }
 87
 88     DFS(1);
 89     DFS2(1,1);
 90
 91     for(int i=1;i<=n;i++)
 92         Updata(1,1,n,ID[i],ID[i],key[i]);
 93     int op,x,a;
 94     while(m--){
 95         scanf("%d",&op);
 96         if(op==1){
 97             scanf("%d%d",&x,&a);
 98             Updata(1,1,n,ID[x],ID[x],a);
 99         }
100         else if(op==2){
101             scanf("%d%d",&x,&a);
102             Updata(1,1,n,ID[x],end[x],a);
103         }
104         else{
105             scanf("%d",&x);
106             printf("%lld\n",Solve(x));
107         }
108     }
109     return 0;
110 }

转载于:https://www.cnblogs.com/TenderRun/p/5337024.html

数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2相关推荐

  1. 数据结构--树链剖分详解

    数据结构--树链剖分详解 关于模板题---->传送门 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将 ...

  2. BZOJ 4034: [HAOI2015]T2 树链剖分

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

  3. 树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count

    这是树链剖分的入门题,也是我学树链剖分的第一题. 树链剖分:就是把树中和线段树联系起来,求(u,v)路径中权值的最大值和其路径的权值和. 入门blog:http://blog.sina.com.cn/ ...

  4. BZOJ 4034 [HAOI2015]T2 树链剖分

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

  5. bzoj 4034: [HAOI2015]树上操作(树链剖分+线段树区间更新)

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 4981  Solved: 1603 [Submit][St ...

  6. BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...

  7. BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)

    毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...

  8. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

  9. BZOJ 3626 LCA(离线+树链剖分+差分)

    显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案.观察到,深度其实就是上面有几个已 ...

最新文章

  1. Transformers 研究指南
  2. vue样式 引入图片_详解Vue.js中引入图片路径的几种方式
  3. Ubuntu Linux 安装 .7z 解压和压缩文件
  4. Android开发之布局--RelativeLayout布局
  5. php validator,实用的PHP验证器类Validator
  6. c++编译器pointer to a function used in arithmetic的解决办法
  7. 计算机专业女兵,陈豪2010《点解阿Sir》剧照
  8. UE4异步编程专题 - TFunction
  9. IOS 如何获取ppi
  10. MySQL表名后接t_mysql表名忽略大小写
  11. 编写javascript、Jquery的String.format();
  12. 阿里巴巴图片滚动代码html,阿里旺铺装修代码的fx.roll滚动特效组件使用详解及HTML代码示例...
  13. Windows Server 2008 R2 Enterpris服务器上安装一个Moodle
  14. 百度云高速下载的两种方法
  15. 前端怎么把word文档转换成HTML格式
  16. KU-600变电站综合自动化系统
  17. Activity流程引擎表结构
  18. 强化学习(1)-什么是强化学习
  19. 【PTA】斐波那契数列第n项
  20. ubuntu 命令行批量重命名文件夹

热门文章

  1. 房贷断供了,房子就要被收走,首付款怎么办?
  2. 真正的蓝海是适合你的领域
  3. 几个互联网巨头的社区团购还不收手?
  4. 500能不能配个玩英雄联盟的电脑?
  5. 如何建立自己的工作库,把分散信息有效整理?
  6. PHP注释php中的注释分为两种:注释和块注释
  7. deepin开机未登录自动连接wifi
  8. Markdown数学公式大全
  9. php无限次执行函数,php – 防止多次执行JavaScript函数
  10. 帆软报表 js 调用sql_SQL Server中的报表–创建由先前创建的主报表调用的基于矩阵的子报表