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 。
 
  

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn=;
int cnt,fir[maxn],to[maxn<<],nxt[maxn<<],n,m;
void addedge(int a,int b){
nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;
}
long long key[maxn],tr[maxn<<],add[maxn<<];
int ID[maxn],fa[maxn],top[maxn],end[maxn],sz[maxn],son[maxn];
void Push_up(int x){
tr[x]=tr[x<<]+tr[x<<|];
}
void Add(int x,int l,int r,long long d){
tr[x]+=(r-l+)*d;
add[x]+=d;
}
void Push_down(int x,int l,int r){
if(add[x]){
int mid=(l+r)>>;
Add(x<<,l,mid,add[x]);
Add(x<<|,mid+,r,add[x]);
add[x]=;
}
}
void Updata(int node,int l,int r,int a,int b,long long d){
if(l>=a&&r<=b){
Add(node,l,r,d);
return;
}
Push_down(node,l,r);
int mid=(l+r)>>;
if(mid>=a)Updata(node<<,l,mid,a,b,d);
if(mid<b) Updata(node<<|,mid+,r,a,b,d);
Push_up(node);
}
long long Query(int node,int l,int r,int a,int b){
if(l>=a&&r<=b)return tr[node];
Push_down(node,l,r);
int mid=(l+r)>>;
long long ret=;
if(mid>=a)ret=Query(node<<,l,mid,a,b);
if(mid<b) ret+=Query(node<<|,mid+,r,a,b);
return ret;
}
void DFS(int x){
sz[x]=;
for(int i=fir[x];i;i=nxt[i]){
if(to[i]==fa[x])continue;
fa[to[i]]=x;
DFS(to[i]);
sz[x]+=sz[to[i]];
son[x]=sz[son[x]]<sz[to[i]]?to[i]:son[x];
}
}
long long Solve(int y){
long long ret=;
while(y){
ret+=Query(,,n,ID[top[y]],ID[y]);
y=fa[top[y]];
}
return ret;
}
int cont;
void DFS2(int x,int tp){
ID[x]=++cont;top[x]=tp;
if(son[x])DFS2(son[x],tp);
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[x]&&to[i]!=son[x])
DFS2(to[i],to[i]);
end[x]=cont;
}
int main(){
freopen("t2.in","r",stdin);
freopen("t2.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i=;i<=n;i++)
scanf("%lld",&key[i]); for(int i=,a,b;i<n;i++){
scanf("%d %d",&a,&b);
addedge(a,b);
addedge(b,a);
} DFS();
DFS2(,); for(int i=;i<=n;i++)
Updata(,,n,ID[i],ID[i],key[i]);
int op,x,a;
while(m--){
scanf("%d",&op);
if(op==){
scanf("%d%d",&x,&a);
Updata(,,n,ID[x],ID[x],a);
}
else if(op==){
scanf("%d%d",&x,&a);
Updata(,,n,ID[x],end[x],a);
}
else{
scanf("%d",&x);
printf("%lld\n",Solve(x));
}
}
return ;
}

数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2的更多相关文章

  1. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  2. Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1841  Solved: 598[Submit][Status] ...

  3. BZOJ 4034: [HAOI2015]T2( 树链剖分 )

    树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...

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

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...

  5. bzoj 4034: [HAOI2015]T2

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

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

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

  7. 数据结构(树链剖分,堆):HNOI 2016 network

    2215. [HNOI2016]网络 ★★★☆   输入文件:network_tenderRun.in   输出文件:network_tenderRun.out   简单对比时间限制:2 s   内存 ...

  8. 数据结构--树链剖分准备之LCA

    有关LCA的模板题    传送门 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和 ...

  9. 数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划

    2109. [NOIP2015] 运输计划 ★★★   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:1 s   内存限制:256 MB [题目描 ...

随机推荐

  1. HTML特效代码大全

    1)贴图:<img src="图片地址">2)加入连接:<a href="所要连接的相关地址">写上你想写的字</a>1)贴 ...

  2. Java方法-数组

    [Java数组] 1. 用sort()方法对Java数组进行排序,及如何使用 binarySearch() 方法来查找数组中的元素 binarySearch() 返回值: 如果它包含在数组中,则返回搜 ...

  3. JavaScript Array(数组) 对象

    更多实例 合并两个数组 - concat() 合并三个数组 - concat() 用数组的元素组成字符串 - join() 删除数组的最后一个元素 - pop() 数组的末尾添加新的元素 - push ...

  4. EBS成本核算方法

    业务背景 成本核算方法,对应EBS系统中的成本方法,有四种: 1.标准成本 2.平均成本 平均成本又分为永续平均成本,即 Average Cost 期间平均成本,按照期间(自然月)来计算的平均成本 F ...

  5. [Client]动检参数讨论与ONVIF

    [问题]客户端访问ONVIF设备动检 客户端要访问ONVIF设备(IPC)的动检,一是事件,二是设置: 此处就是讨论如何设置动检区域的. 通过Video Analytics/Cell Motion D ...

  6. 『重构--改善既有代码的设计』读书笔记----Extract Class

    在面向对象中,对于类这个概念我们应该有一个清晰的责任认识,就是每个类应该只有一个变化点,每个类的变化应该只受到单一的因素,即每个类应该只有一个明确的责任.当然了,说时容易做时难,很多人可能都会和我一样 ...

  7. Debian 8.0(Jessie) 无线网卡,ATI显卡驱动和输入法等安装记录。

    转载请注明作者与出处!谢谢! 最近准备彻底转换到Linux平台,之前一直用的是Red Hat,对Debian不是很熟悉,花了不少时间摸索.下面记录一下安装的过程以便备忘,顺便给他人能做个参考. 我的是 ...

  8. css+js自动化开发之第十五天

    一.css上一篇的补充 1.position(页面分层) (1)fiexd将标签固定在页面的某个位置 position属性:top,left,right,bottom (2)relative+abso ...

  9. python 时间戳

    import timeprint time.time()输出的结果是(单位:s):1395421406.39 x = time.localtime(x) x = time.strftime('%Y-% ...

  10. C++实现base64编码(1)

    下面的代码是php里面的base64编码逻辑,确实比我之前的要美观很多,我只是简单的用C++的类进行了一下封装,删除了一些没用的逻辑,基本上还是原来PHP的代码: #include <iostr ...