这个题多了一个操作难度直线上升,看完题解才会写

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

按照题意:记录其DFS序,然后进栈是正,出栈为负,利用线段树进行更新

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <stack>
using namespace std;
typedef long long LL;
const int N = ;
struct Edge
{
int v,next;
} edge[N<<];
int head[N],tot,cnt;
int val[N];
int in[N],out[N];
LL tree[N<<],lazy[N<<],seg[N];
int flag[N<<];
int io[N];
void addEdge(int u,int v)
{
edge[tot].v = v,edge[tot].next = head[u],head[u] = tot++;
}
void init()
{
memset(head,-,sizeof(head));
memset(val,,sizeof(val));
memset(lazy,,sizeof(lazy));
memset(io,,sizeof(io));
memset(seg,,sizeof(seg));
tot = cnt = ;
}
void dfs(int u,int fa)
{
seg[in[u] = ++cnt] = (LL)val[u];
io[cnt] = ;
for(int i=head[u]; i!=-; i=edge[i].next)
{
if(edge[i].v != fa)
{
dfs(edge[i].v,u);
}
}
seg[out[u] = ++cnt] = (LL)(-val[u]);
io[cnt] = -;
} void pushup(int idx)
{
tree[idx] = tree[idx<<]+tree[idx<<|];
return;
}
void pushdown(int idx)
{
if(lazy[idx])
{
tree[idx << ] += flag[idx<<]*lazy[idx];
tree[idx << | ] += flag[idx<<|]*lazy[idx];
lazy[idx << ] += lazy[idx];
lazy[idx << | ] += lazy[idx];
lazy[idx] = ;
}
return;
}
void build(int l,int r,int idx)
{
if(l==r)
{
tree[idx] = seg[l];
if(io[l]>) flag[idx] = ;
else flag[idx] = -;
return;
}
int mid = (l+r)>>;
build(l,mid,idx<<);
build(mid+,r,idx<<|);
pushup(idx);
flag[idx] = flag[idx<<] + flag[idx<<|];
}
void update(int l,int r,int L,int R,int idx,int val)
{
if(l>=L&&r<=R)
{
tree[idx] =tree[idx] + (LL)flag[idx]*val;
lazy[idx] =lazy[idx] + (LL)val;
return;
}
int mid = (l+r)>>;
pushdown(idx);
if(mid>=L) update(l,mid,L,R,idx<<,val);
if(mid<R) update(mid+,r,L,R,idx<<|,val);
pushup(idx);
}
LL query(int l,int r,int L,int R,int idx){
if(l>=L&&r<=R)
{
return tree[idx];
}
int mid = (l+r)>>;
LL sum = ;
pushdown(idx);
if(mid>=L) sum+=query(l,mid,L,R,idx<<);
if(mid<R) sum+=query(mid+,r,L,R,idx<<|);
return sum;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=; i<=n; i++)
{
scanf("%d",&val[i]);
}
for(int i=; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
dfs(,);
build(,*n,);
while(m--)
{
int op,x,y;
scanf("%d",&op);
if(op==)
{
scanf("%d%d",&x,&y);
update(,*n,in[x],in[x],,y);
update(,*n,out[x],out[x],,y);
}else if(op==){
scanf("%d%d",&x,&y);
update(,*n,in[x],out[x],,y);
}else{
scanf("%d",&x);
LL sum = query(,*n,,in[x],);
printf("%lld\n",sum);
}
}
}
}

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

  1. BZOJ 1103 DFS序+线段树

    思路: 先搞出来DFS序 进入这个点 +1 出这个点 -1 线段树维护前缀和 (因为还要修改) 搞定 修改的时候只修改底下节点就OK了 (边权–>点权 不多说) //By SiriusRen # ...

  2. BZOJ 2819 DFS序+线段树

    非递归的DFS写炸了- 交了一个递归版的 过了---.. //By SiriusRen #include <cstdio> #include <cstring> #includ ...

  3. DFS序+线段树(bzoj 4034)

    题目链接 题目就不多说了. 本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值.我们可以先将这棵树进行dfs将一棵树变成线性结构:如图 变成这样后,然后就可以用线段树. 操作1:也 ...

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

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

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

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

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

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

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

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

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

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

  9. POJ 3321 DFS序+线段树

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

随机推荐

  1. Angular http跨域

    原文:Angular http跨域 - 飞翔的小仓鼠 - 博客园 var app = angular.module('Mywind',['ui.router']); app.controller('M ...

  2. 简短的创建Ajax对象代码

    假如你的脚本只针对某个浏览器开发,那么创建XMLHTTP是很简单的一件事,用XMLHttpRequest或者ActiveXObject即可.但事实上绝大多数的时候,我们都要考虑兼容,于是我们通常写成: ...

  3. imuxsock lost 353 messages from pid 20261 due to rate-limiting 解决办法

    日志中出现大量一下日志时 May 24 18:42:08 yw_lvs2_backup rsyslogd-2177: imuxsock lost 353 messages from pid 20261 ...

  4. Spss22安装与破解步骤

    Spss22安装与破解教程 向师姐请教了一些学术问题,哈哈说的有点大,不过真的很感谢,学到了很多,少走了很多弯路. 1.下载安装包 可以去IBM官网.人大论坛等网站下载,全部文件应包括spss22安装 ...

  5. 1.Qt简介

    附件列表 1.Qt简介.png

  6. 【python】python安装lxml报错【2】

    cl : Command line warning D9025 : overriding '/W3' with '/w' lxml.etree.c c:\docume~\admini~.chi\loc ...

  7. aapt命令说明

    这里借用一下百度百科,我比较懒 1.列出apk包的内容 aapt l[ist] [-v] [-a] <你的应用> -v 以table形式列出来 -a 详细列出内容 例如:aapt l &l ...

  8. php 通过链接生成二维码,扫码支付用到

    $(".good_info").on('click',function () { var id = $(this).data('id'); var string='http://q ...

  9. Kubernetes Pod 健康检查

    参考文档: https://jimmysong.io/kubernetes-handbook/guide/configure-liveness-readiness-probes.html 一.Pod的 ...

  10. [大数据]-hadoop2.8和spark2.1完全分布式搭建

    一.前期准备工作: 1.安装包的准备: VMware(10.0版本以上) : 官方网站:https://www.vmware.com/cn.html 官方下载地址:http://www.vmware. ...