题目就不多说了。
本题目,可以用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. 修改ViewPager调用setCurrentItem时,滑屏的速度 ,解决滑动之间切换动画难看

    在使用ViewPager的过程中,有需要直接跳转到某一个页面的情况,这个时候就需要用到ViewPager的setCurrentItem方法了,它的意思是跳转到ViewPager的指定页面,但在使用这个 ...

  2. 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”

    首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中对本模块提供给其它模块 ...

  3. 【Tensorflow】tf.argmax函数

    tf.argmax(input, axis=None, name=None, dimension=None) 此函数是对矩阵按行或列计算最大值   参数 input:输入Tensor axis:0表示 ...

  4. python matplotlib imshow热图坐标替换/映射

    今天遇到了这样一个问题,使用matplotlib绘制热图数组中横纵坐标自然是图片的像素排列顺序, 但是这样带来的问题就是画出来的x,y轴中坐标点的数据任然是x,y在数组中的下标, 实际中我们可能期望坐 ...

  5. 【搞机】9.7英寸iPad Pro 上手开箱(图文)

    前言 话说,去年就一直想买个iPad ,可是苦于iPad air 2 出的太早,立即就要更新了,就没有买. 今年出了9.7英寸的iPad Pro .看到添加了这么多新特性.就按耐不住心情预订了~ 还刻 ...

  6. 分布式数据库数据从属与client与server的数据同步

    老实说,眼下市面上很多产品,的确是不成熟的产品. 用过一些,给人蛋痛的感觉. 导言 分布还是集总 今天我们来探讨一个非常重要的问题. 每一个程序猿都有其思想,我的思想之中的一个,就是分布式. 分布式, ...

  7. Phalcon框架如何实现读写分离

    Phalcon框架如何实现读写分离 假设你已经在DI容器里注册了俩 db services,如下: <?php // 主库 $di->setShared('dbWrite', functi ...

  8. FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解(转)

    1.StorageClient与StorageClient1的区别 相信使用happy_fish的FastDFS的童鞋们,一定都熟悉StorageClient了,或者你熟悉的是StorageClien ...

  9. caffe2 安装与介绍

    http://blog.csdn.net/yan_joy/article/details/70241319 标签: 深度学习 2017-04-19 15:31 5970人阅读 评论(0) 收藏 举报 ...

  10. POJ 1952 BUY LOW, BUY LOWER 动态规划题解

    Description The advice to "buy low" is half the formula to success in the bovine stock mar ...