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)

 #include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
#define MAXN (100000+50)
using namespace std;
LL Tree[MAXN];
LL T_num[MAXN];
LL Depth[MAXN];
LL Father[MAXN];
LL Sum[MAXN];
LL Son[MAXN];
LL Top[MAXN];
LL a[MAXN];
LL n,m,u,v,sum;
LL head[MAXN],num_edge;
struct node1
{
LL val;
LL add;
} Segt[MAXN*];
struct node2
{
LL to;
LL next;
} edge[MAXN*];
void add(LL u,LL v)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
head[u]=num_edge;
} void Dfs1(LL x)
{
Sum[x]=;
Depth[x]=Depth[Father[x]]+;
for (LL i=head[x]; i!=; i=edge[i].next)
if (edge[i].to!=Father[x])
{
Father[edge[i].to]=x;
Dfs1(edge[i].to);
Sum[x]+=Sum[edge[i].to];
if (Son[x]== || (Sum[Son[x]]<Sum[edge[i].to]))
Son[x]=edge[i].to;
}
} void Dfs2(LL x,LL tp)
{
T_num[x]=++sum;
Tree[sum]=a[x];
Top[x]=tp;
if (Son[x])
Dfs2(Son[x],tp);
for (LL i=head[x]; i!=; i=edge[i].next)
if (edge[i].to!=Son[x] && edge[i].to!=Father[x])
Dfs2(edge[i].to,edge[i].to);
} void Pushdown(LL node,LL l,LL r)
{
if (Segt[node].add!=)
{
LL mid=(l+r)/;
Segt[node*].val+=Segt[node].add*(mid-l+);
Segt[node*+].val+=Segt[node].add*(r-mid);
Segt[node*].add+=Segt[node].add;
Segt[node*+].add+=Segt[node].add;
Segt[node].add=;
}
} void Build(LL node,LL l,LL r)
{
if (l==r)
Segt[node].val=Tree[l];
else
{
LL mid=(l+r)/;
Build(node*,l,mid);
Build(node*+,mid+,r);
Segt[node].val=Segt[node*].val+Segt[node*+].val;
}
} void Update(LL node,LL l,LL r,LL l1,LL r1,LL k)
{
if (l>r1 || r<l1)
return;
if (l1<=l && r<=r1)
{
Segt[node].val+=(r-l+)*k;
Segt[node].add+=k;
return;
}
Pushdown(node,l,r);
LL mid=(l+r)/;
Update(node*,l,mid,l1,r1,k);
Update(node*+,mid+,r,l1,r1,k);
Segt[node].val=Segt[node*].val+Segt[node*+].val;
} LL Query(LL node,LL l,LL r,LL l1,LL r1)
{
if (l>r1 || r<l1)
return ;
if (l1<=l && r<=r1)
return Segt[node].val;
Pushdown(node,l,r);
LL mid=(l+r)/;
return Query(node*,l,mid,l1,r1)+Query(node*+,mid+,r,l1,r1);
} LL Get(LL x)
{
LL ans=;
while (x!=)
{
ans+=Query(,,n,T_num[Top[x]],T_num[x]);
x=Father[Top[x]];
}
return ans;
} int main()
{
scanf("%lld%lld",&n,&m);
for (LL i=; i<=n; ++i)
scanf("%lld",&a[i]);
for (LL i=; i<=n-; ++i)
{
scanf("%lld%lld",&u,&v);
add(u,v);
add(v,u);
}
Dfs1();
Dfs2(,);
Build(,,n);
for (LL i=; i<=m; ++i)
{
LL p,x,y;
scanf("%lld",&p);
if (p==)
{
scanf("%lld%lld",&x,&y);
Update(,,n,T_num[x],T_num[x],y);
}
if (p==)
{
scanf("%lld%lld",&x,&y);
Update(,,n,T_num[x],T_num[x]+Sum[x]-,y);
}
if (p==)
{
scanf("%lld",&x);
printf("%lld\n",Get(x));
}
}
}

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. Android全屏的两种方法

    在开发中我们经常需要把我们的应用设置为全屏,这里我所知道的有俩中方法,一中是在代码中设置,另一种方法是在配置文件里改! 一.在代码中设置: [java] view plain copy package ...

  2. Java虚拟机_运行时数据区

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途.各自的创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程启动 ...

  3. 哈夫曼编码(Huffman coding)的那些事,(编码技术介绍和程序实现)

    前言 哈夫曼编码(Huffman coding)是一种可变长的前缀码.哈夫曼编码使用的算法是David A. Huffman还是在MIT的学生时提出的,并且在1952年发表了名为<A Metho ...

  4. HTTP2 帧基础知识以及Header、CONTINUATION、DATA帧相关资料:

    HTTP2于2015年2月28日正式通过IETF组织批准发布,正式定稿.有关它的内容可以参考:  HTTP2 概述  http://www.cnblogs.com/ghj1976/p/4552583. ...

  5. JS 中的布尔运算符 && 和 ||

    布尔运算符 && 和 ||的返回结果不一定是布尔值!由此来展开一定的研究及理解. 1.首先先介绍下常见的数据类型转化为bool后的值. (常用地方)在if表达式中,javascript ...

  6. html基础-标题标签-文字标签(2)

    昨天说道了我的第一个网页,今天接着继续带大家深入,前期学习千万不要用代码工具哦!那样就少了深入了解的机会了哦! 一.大家都知道文章会有各种标题,网页其实也跟文章差不多也有专门来写标题的元素. (1). ...

  7. opencv3.2.0图像离散傅里叶变换

    源码: ##名称:离散傅里叶变换 ##平台:QT5.7.1+opencv3.2.0 ##日期:2017年12月13. /**** 新建QT控制台程序****/ #include <QCoreAp ...

  8. 一个Interface 继承多个Interface 的总结

    我们知道在Java中的继承都是单继承的,就是说一个父类可以被多个子类继承但是一个子类只能有一个父类.但是一个接口可以被不同实现类去实现,这就是我们说的Java中的多态的概念.下面我们再来说一下接口的多 ...

  9. 'webpack' 不是内部或外部命令,也不是可运行的程序 或批处理文件。

    npm updatea -g 很严重,把本地npm安装包都更新了,跟项目npm安装包版本不一,导致 意思是版本冲突,手动卸载了,重新安装还是最新版本,很是头疼.找同事的电脑拷贝了一份,然后复制过来报“ ...

  10. tomcat idea optinos

    -server -XX:PermSize=128M -XX:MaxPermSize=256m -Xms512m -Xmx1024m