bzoj 4034(DFS序+线段树)
这个题多了一个操作难度直线上升,看完题解才会写
有一棵点数为 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序+线段树)的更多相关文章
- BZOJ 1103 DFS序+线段树
思路: 先搞出来DFS序 进入这个点 +1 出这个点 -1 线段树维护前缀和 (因为还要修改) 搞定 修改的时候只修改底下节点就OK了 (边权–>点权 不多说) //By SiriusRen # ...
- BZOJ 2819 DFS序+线段树
非递归的DFS写炸了- 交了一个递归版的 过了---.. //By SiriusRen #include <cstdio> #include <cstring> #includ ...
- DFS序+线段树(bzoj 4034)
题目链接 题目就不多说了. 本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值.我们可以先将这棵树进行dfs将一棵树变成线性结构:如图 变成这样后,然后就可以用线段树. 操作1:也 ...
- BZOJ 3252题解(贪心+dfs序+线段树)
题面 传送门 分析 此题做法很多,树形DP,DFS序+线段树,树链剖分都可以做 这里给出DFS序+线段树的代码 我们用线段树维护到根节点路径上节点权值之和的最大值,以及取到最大值的节点编号x 每次从根 ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- POJ 3321 DFS序+线段树
单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4: 5: #include < ...
随机推荐
- opencv 应用程序无法正常启动(0xooooo7b)
#include<iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui ...
- Chapter1(预科)--C++Prime笔记
心得体会: 因为之前一直在用在学C,因此在看完C++Prime第一章后,就有中在一个培训班中,一个老师用一个简单的项目来带你了解这种语言的特性的感觉.当然这个告诉是在让你脑子固化接受一些点的前提下. ...
- linux命令总结之dig命令
Dig简介: Dig是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,MX记录等相关信息的工具.Dig的源码是ISC BIND大包的一部分,但是大多编译和安装Bind的文档都不把它包括在内 ...
- Linux运维二:CentOS6.6系统安装后的基本配置与优化
CentOS6.6系统安装完成后还需要做一些配置与优化: 一:Linux内核版本号介绍 查看内核版本: [root@Gin scripts]# uname -r 2.6.32-504.el6.x86_ ...
- [2009国家集训队]小Z的袜子(hose) 浅谈莫队
浅谈莫队 推荐学习博客 http://foreseeable97.logdown.com/posts/158522-233333 借用题目: bzoj 2038 2009 国家集训队 小Z的袜子htt ...
- COGS 栅格网络流
750. 栅格网络流 http://www.cogs.pro/cogs/problem/problem.php?pid=750 ★★☆ 输入文件:flowa.in 输出文件:flowa.out ...
- Codeforces刷题计划
Codeforces刷题计划 已完成:-- / -- [Codeforces370E]370E - Summer Reading:构造:(给定某些数,在空白处填数,要求不下降,并且相邻差值<=1 ...
- jquery $.post() 向php传值 实现简单的二级联动
更多内容推荐微信公众号,欢迎关注: 1 其中selectid是一个下拉菜单的id $().ready(function () { $("#selectid").change(fun ...
- yii验证系统学习记录,基于yiicms(一)写的太长了,再写一篇(二)
项目地址:https://gitee.com/templi/yiicms 感谢七觞酒大神的付出,和免费分享.当然也感谢yii2的开发团队们. 项目已经安全完毕,不知道后台密码,这种背景下,后台无法进去 ...
- 使用solr批量导入mysql数据库,以及Unable to read: dataimport.properties等坑
折腾了一下午终于成功了!先放一张成功图: 成功把mysql的数据添加进去了,我这里是整合了tomcat9,整合步骤挺麻烦的,百度一大堆! 这里主要介绍批量导入数据,这里有些坑,所以记录一下: 步骤: ...