题目就不多说了。
本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值。我们可以先将这棵树进行dfs将一棵树变成线性结构:如图
变成这样后,然后就可以用线段树。
  • 操作1:也就是将某两个点+a;
  • 操作2:区间更新
  • 操作3:查询起始区间到某点的和
我们建线段树,需要统计 +,- 抵消后的个数,因为要知道该区间的和,需要知道+a;
简单插线问线。
代码---参考下面链接吧或者我的
友情提示:注意爆int,计算的时候注意是否超int范围;所以wa了好多次。。。
 #include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long LL;
const int INF=2e9+1e8; const int MOD=1e9+;
const double eps=0.0000000001;
void fre()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
#define MSET(a,b) memset(a,b,sizeof(a)) const int maxn=1e6+;
void zpsb(int x)
{
if(x>=&&x<maxn) return ;
while();
}
struct Edge
{
int t,next;
}edge[maxn];
int sz,first[maxn],Treeval[maxn];
void addedge(int s,int t)
{
edge[sz].t=t,edge[sz].next=first[s];
first[s]=sz++;
}
int in[maxn],out[maxn];
int reid[maxn],io[maxn],tot;
void dfs(int x,int pre)
{
reid[in[x]=tot]=Treeval[x];
io[tot++]=;
for(int i=first[x];i!=-;i=edge[i].next)
{
int t=edge[i].t;
if(t==pre) continue;
dfs(t,x);
}
reid[out[x]=tot]=-Treeval[x];
io[tot++]=-;
} struct SegTree
{
struct Node
{
int l,r,flag;
LL lazy,sum;
}T[maxn*];
void build(int i,int l,int r)
{
T[i].l=l,T[i].r=r;
T[i].lazy=T[i].flag=;
if(l==r)
{
T[i].sum=reid[r];
T[i].flag=io[r];
return ;
}
int mid=(l+r)>>;
build(i<<,l,mid),build(i<<|,mid+,r);
T[i].sum=T[i<<].sum+T[i<<|].sum;
T[i].flag=T[i<<].flag+T[i<<|].flag;
}
void pushdown(int i)
{
if(T[i].lazy)
{
T[i<<].sum+=T[i].lazy*T[i<<].flag;
T[i<<|].sum+=T[i].lazy*T[i<<|].flag;
T[i<<].lazy+=T[i].lazy,T[i<<|].lazy+=T[i].lazy;
T[i].lazy=;
}
}
void update(int i,int l,int r,LL k)
{
zpsb(i);
if(T[i].l==l&&T[i].r==r)
{
T[i].sum+=T[i].flag*k;
T[i].lazy+=k;
return ;
}
pushdown(i);
int mid=(T[i].l+T[i].r)>>;
if(r<=mid) update(i<<,l,r,k);
else if(l>mid) update(i<<|,l,r,k);
else update(i<<,l,mid,k),update(i<<|,mid+,r,k);
T[i].sum=T[i<<].sum+T[i<<|].sum;
}
LL query(int i,int l,int r)
{
if(T[i].l==l&&T[i].r==r) return T[i].sum;
pushdown(i);
int mid=(T[i].l+T[i].r)>>;
if(r<=mid) return query(i<<,l,r);
else if(l>mid) return query(i<<|,l,r);
else return query(i<<,l,mid)+query(i<<|,mid+,r);
}
}wa;
int main()
{
int n,m;
MSET(first,-);
sz=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&Treeval[i]);
for(int i=;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
tot=;
dfs(,);
// for(int i=1;i<=n;i++)
// {
// printf("x=%d %d %d\n",i,in[i],out[i]);
// }
// for(int i=1;i<=2*n;i++)
// {
// printf("id=%d val=%d\n",i,reid[i]);
// }
wa.build(,,*n);
while(m--)
{
int opt;
scanf("%d",&opt);
if(opt==)
{
int x,a;
scanf("%d%d",&x,&a);
wa.update(,in[x],in[x],(LL)a);
wa.update(,out[x],out[x],(LL)a);
}
else if(opt==)
{
int x,a;
scanf("%d%d",&x,&a);
wa.update(,in[x],out[x],(LL)a);
}
else
{
int x;
scanf("%d",&x);
printf("%lld\n",wa.query(,,in[x]));
}
}
} /**************************************************/
/** Copyright Notice **/
/** writer: wurong **/
/** school: nyist **/
/** blog : http://blog.csdn.net/wr_technology **/
/**************************************************/

DFS序+线段树(bzoj 4034)的更多相关文章

  1. BZOJ 3252题解(贪心+dfs序+线段树)

    题面 传送门 分析 此题做法很多,树形DP,DFS序+线段树,树链剖分都可以做 这里给出DFS序+线段树的代码 我们用线段树维护到根节点路径上节点权值之和的最大值,以及取到最大值的节点编号x 每次从根 ...

  2. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  3. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  4. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  5. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

  6. POJ 3321 DFS序+线段树

    单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4:   5: #include < ...

  7. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

  8. F - Change FZU - 2277 (DFS序+线段树)

    题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...

  9. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

随机推荐

  1. VMWare 无损扩展磁盘大小

    1. 所需文件(gparted) 可以去gparted主页下载LiveCD 下载地址:http://sourceforge.net/projects/gparted/files/gparted/ 或百 ...

  2. Android --修改arr文件

    1. 改为zip文件 2. 修改 3. 改后缀

  3. Activiti 流程部署方式 activi 动态部署(高级源代码篇)

    Activiti的流程 部署方式有非常多种方式,我们能够依据activit工作流引擎提供的ap方式进行部署. 当然了实际需求决定你要使用哪一种api操作,后面的总结具体介绍了使用场景. 以下看一下部署 ...

  4. SSH 原理和公匙私匙

    先主要介绍了Telnet.SSH 的通信原理,分析了其通信时的工作流程. Telnet 无论Telnet协议连接的是什么类型终端,都会转换为NVT(Net Virtual Terminal)格式进行通 ...

  5. Lead软件项目半年感受

    Lead一个项目快半年了,整体来说是个辛苦活. 除了自己的研发进度,还要负责对上,对下,对外的交流.这里记录一些感受.     对上的交流,除了确保正确理解老大的安排.就是确保老大在和他的lead以及 ...

  6. B树的生成

    B树的生成 flyfish 2015-7-19 从空树開始构建一棵B树 逐个插入keyword 规则: 除根结点之外的全部非终端结点至少有⌈m/2⌉棵子树,所以keyword的个数必须 n为keywo ...

  7. JavaScript读书笔记(3)-操作符、语句和函数

    1.  操作符 (1)       一元操作符 前置递增和递减操作符,变量的值都是在语句被求值以前改变的:后置相反 (2)       位操作符 在ECMAScript中,对数值进行位操作时,会发生以 ...

  8. xpath 轴,节点之间的关系

    http://www.w3school.com.cn/xpath/xpath_axes.asp http://www.freeformatter.com/xpath-tester.html 测试 轴可 ...

  9. 基于UDP的一对回射客户/服务器程序

    前言 之前曾经学习过一对回射客户/服务器程序的例子,不过那个是基于TCP协议的.本文将讲解另一对回射客户/服务器程序,该程序基于UDP协议.由于使用的协议不同,因此编写出的程序也有本质上的区别,应将它 ...

  10. 如何获取ipa 包的图片

    突然想起当初刚学习iOS的时候,就经常通过抓包和提取素材的方式来模仿App,今天就教大家如何一步步提取App的素材! 大家是否有过想要获取别人的素材的想法?看到某些App的资源很不错,很想导出来用用, ...