题目就不多说了。
本题目,可以用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. 26个高效工作的小技巧 z

    1.时间常有,时间优先. 2.时间总会有的:每天只计划4-5 小时真正的工作. 3.当你在状态时,就多干点:不然就好好休息:有时候会连着几天不是工作状态,有时在工作状态时却又能天天忙活 12 小时,这 ...

  2. Neural Networks for Machine Learning by Geoffrey Hinton (1~2)

    机器学习能良好解决的问题 识别模式 识别异常 预測 大脑工作模式 人类有个神经元,每一个包括个权重,带宽要远好于工作站. 神经元的不同类型 Linear (线性)神经元  Binary thresho ...

  3. Android--------------几个ADB经常使用命令

    1. 显示当前执行的所有模拟器:     adb devices 2. 安装应用程序:     adb install -r 123.apk 3. 获取模拟器中的文件:     adb pull &l ...

  4. 阿里巴巴为什么主推HSF?比Dubbo有哪些优势?

    作者:匿名用户链接:https://www.zhihu.com/question/39560697/answer/187538165来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  5. mysql 导入sql文件时自动切换了大小写

    windows环境下: 解决办法(即将其改为大小写敏感): 在my.ini中添加 lower_case_table_names=1

  6. Effective C++ 条款一 视C++为一个语音联邦

    1.C语言         区块.语句.预处理器.内置数据类型.数组.指针等内容 2.OC++       类.封装.继承.多态.virtual函数 等 3.Template C++       泛型 ...

  7. 手写AngularJS脏检查机制

    什么是脏检查 View -> Model 浏览器提供有User Event触发事件的API,例如,click,change等 Model -> View 浏览器没有数据监测API. Ang ...

  8. vmware克隆一台机器后修改etho

    1 vi /etc/udev/rules.d/70-persistent-net.rules 2 注释NAME="eth0"的内容 3 将NAME="eth1" ...

  9. Arduino关于旋转编码器程序的介绍(Reading Rotary Encoders)--by Markdown

    介绍 旋转或编码器是一个角度測量装置. 他用作精确測量电机的旋转角度或者用来控制控制轮子(能够无限旋转,而电位器只能旋转到特定位置).其中有一些还安装了一个能够在轴上按的button,就像音乐播放器的 ...

  10. git+jenkins

    开发写代码的演变 一个开发单打独斗,撸代码,开发网站,自由自在 多个开发同时开发一个网站,同时改一份代码.但是同时改一个文件会导致冲突 分支结构,每天上班第一件事克隆代码,下班前最后一件事合并代码 好 ...