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. MyEclipse中设置代码块快捷键

    如果想用快捷键生成一段自定义代码,可以通过下面方式设置: Java->Editor->Templates->New 如果要设置或者更改某个快捷键,如要设置保存全部文档的快捷键(系统默 ...

  2. leetcode实践:找出两个有序数组的中位数

    题目 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 代码实现 package com. ...

  3. js实现unicode码字符串与utf8字节数据互转

    js的string变量存储字符串使用的是unicode编码,要保存时必须选择其他编码后进行传输,比如转成utf-8,utf-32等.存储到数据库中为utf-8编码,读取出来如何转换成正确的字符串就成了 ...

  4. Hive可视化工具

    目前市面上的Hive可视化客户端工具,大都是C/S模式的,安装使用都不是太方便,目前有一款基于WEB的可视化工具TreeSoft,通过浏览器就可以访问使用了,并且可以同时管理.维护.监控MySQL,O ...

  5. UML 类图详解

    转载来源:http://blog.csdn.net/shift_wwx/article/details/79205187 可以参考:http://www.uml.org.cn/oobject/2012 ...

  6. AutoFac使用方法总结二:事件与依赖循环

         事件 AutoFac支持三种事件:OnActivating,OnActivated,OnRelease.OnActivating在注册组件使用之前会被调用,此时可以替换实现类或者进行一些其他 ...

  7. 中小型研发团队架构实践七:集中式日志ELK

    一.集中式日志 日志可分为系统日志.应用日志以及业务日志,系统日志给运维人员使用,应用日志给研发人员使用,业务日志给业务操作人员使用.我们这里主要讲解应用日志,通过应用日志来了解应用的信息和状态,以及 ...

  8. QT5.4.2静态编译(包含QtWebKit),在VS2013上创建项目,并成功运行

            Qt项目发布的exe程序,默认是以动态链接形式的,这样发布后的程序会附带好多Qt自己的dll库,这样文件数量不仅多,而且移植到其他电脑上的时候,还可能会遇到,提示缺其他库等各种运行不起 ...

  9. 什么是Github?

    初识Github GitHub 是程序员的必备技能 1.什么是Github? 确切的说 GitHub 是一家公司,位于旧金山,由 Chris Wanstrath, PJ Hyett 与 Tom Pre ...

  10. svn 同步资源库时忽略某些文件类型和文件夹

    项目开发中,开发人员经常用SVN来管理代码,在和服务器同步时,每次都看到一堆.class,.log,target等文件,这样很不舒服. 解决方法: 打开:window-->preferences ...