题目就不多说了。
本题目,可以用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. linux如和对其他用户隐藏进程?

    Linux kernel 3.2以上,root用户可以设置内核,让普通用户看不到其它用户的进程.适用于有多个用户使用的系统.该功能由内核提供,因此本教程适用于Debian/Ubuntu/RHEL/Ce ...

  2. 第五讲_图像识别之图像检测Image Detection

    第五讲_图像识别之图像检测Image Detection 目录 物体检测 ILSVRC竞赛200类(每个图片多个标签):输出类别+Bounding Box(x,y,w,h) PASCAL VOC 20 ...

  3. poj 1651 Multiplication Puzzle【区间DP】

    题目链接:http://poj.org/problem? id=1651 题意:初使ans=0,每次消去一个值,位置在pos(pos!=1 && pos !=n) 同一时候ans+=a ...

  4. javascript 高级编程系列 - 继承

    1. 原型链继承 (缺点:子类继承父类的引用类型的属性值会在各个实例中共享,创建子类实例时无法向父类构造函数传递参数) // 定义父类构造函数 function SuperClass(father, ...

  5. centos创建本地yum仓库

    怎样发布自己软件的安装和更新YUM源 在创建之前,我们先了解些相关的内容: yum仓库可以支持三种途径提供给yum在安装的时候下载rpm包 第一种:  ftp服务  ftp:// 第二种:  http ...

  6. kubernetes集群管理常用命令一

    系列目录 我们把集群管理命令分为两个部分,第一部分介绍一些简单的,但是可能是非常常用的命令以及一些平时可能没有碰到的技巧.第二部分将综合前面介绍的工具通过示例来讲解一些更为复杂的命令. 列出集群中所有 ...

  7. nodejs websocket 聊天应用

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...

  8. iOS移动开发周报-第18期

    iOS移动开发周报_18期 [摘要]:本期iOS移动开发周报带来如下内容:苹果与 IBM 展开长期深度合作,Swift官方博客,Swift开发的视频教程等. 新闻 <苹果与 IBM 展开长期深度 ...

  9. WPF3.5 使用BINDINGGROUP进行实体类和集合验证

    前文介绍了自定义或系统自带的ValidationRule进行验证,这种方法对于单个元素的验证不错.很多时候,我们需要对表单(Form)进行验证,也就是对一个实体类进行验证,或者对一个集合的每项进行验证 ...

  10. sql server t-sql脚本转成oracle plsql

    将一份SQL SERVER数据库生成的T-SQL脚本,转成ORACLE的PL/SQL,其复杂繁琐程度,远远出乎我的意料. 这份SQL SERVER脚本,里面有表,有视图,还有存储过程,以及一些自定义函 ...