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 < ...
随机推荐
- 【位运算】判断一个数是否为2的n次方
import java.util.Scanner; /** * 功能:用位运算,判断一个数是否为2的n次方. * 思路:用1做移位操作,然后判断移位后的值是否与给定的数相同. */ public cl ...
- 利用机器学习实现微信小程序-加减大师自动答题
之前有看到微信小程序<跳一跳>别人用python实现自动运行,后来看到别人用hash码实现<加减大师>的自动答题领取娃娃,最近一直在研究深度学习,为啥不用机器学习实现呢?不就是 ...
- Feign来调用服务
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解.Feign支持可 ...
- web项目中配置文件的加载顺序
当一个项目启动时,首先是web.xml: 这里面的配置: 为什么要在web.xml中配置struts的过滤器? 因为一个web项目运行的时需要加载的,或者默认的部分配置都会在web.xml中配置,中间 ...
- RF parameter
There are primarily 3 features which can be tuned to improve the predictive power of the model : 说明: ...
- 安装mysql-5.6版本步骤与卸载
官网下载完解压后: 1.环境变量配置Path D:\mysql-5.6.40-winx64\bin(你的mySql5.6的路径到bin)2.找到D:\mysql-5.6.40-winx64文件中的 ...
- Java多态性的“飘渺之旅”
原文出处:斯武丶风晴 摘要: 如何从Java多态性进行飘渺之旅呢? 我们用例子来旅行. 朵星人A:人类,是一个很奇妙的物种. 朵星人B:他们好像分为两种,嗯 先生,以及美女? 朵星人C:对,更年轻的有 ...
- printf与fprintf函数的区别
printf是标准输出流的输出函数,用来向屏幕这样的标准输出设备输出,而fprintf则是向文件输出,将输出的内容输出到硬盘上的文件或是相当于文件的设备上 printf是有缓冲的输出,fprintf没 ...
- asp.net webapi http请求生命周期
先附上webapi http生命周期图. 原始的图片地址为:https://www.asp.net/media/4071077/aspnet-web-api-poster.pdf
- CentOS6.5本地yum源配置
1. 建立本地源目录及挂载临时目录 2. 挂载光盘 3. 进入/etc/yum.repos.d/目录,将 CentOS-Base.repo CentOS-Debuginfo.repo CentOS-V ...