参考:https://www.cnblogs.com/liyinggang/p/5965981.html

题意:是一个数据结构题,树上的,用dfs序,变成线性的;

思路:对于每一个节点x,记录其DFS序,包括第一次到的序号,用in【x】记录,离开的序号out【x】记录,

再开一个数组seg,in:(序号——>节点的值);out:(序号——>节点的负值);

这样就可以使得

  对于树来说:若所求的一个区间完全包含一个不相关子树,这个子树对结果不影响;

  对于基于 线性 的线段树来说,同时包含in【x】、out【x】区间,区间求和为0;

利用线段树build 数组seg,得到区间的加和;

所以,

1-->分别更新in【x】,out【x】所对应的值;

2-->update in【x】到out【x】区间的值;

3-->返回 1 (根) 到 in【x】 区间的即可;

#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = ;
ll sum[maxn*];
ll seg[maxn],a[maxn],lazy[maxn*],flag[maxn*];
ll in[maxn],out[maxn];
ll io[maxn];
int cnt = ;
int n,m;
vector <int> mp[maxn];
void dfs(int u,int fa)
{
cnt++;
seg[cnt] = 1ll*a[u],in[u] = 1ll*cnt;
for(int i=; i< mp[u].size(); i++)
{
int tmp = mp[u][i];
if(tmp == fa)continue;
dfs(tmp,u);
}
cnt++;
seg[cnt] = -1ll*a[u],out[u] = 1ll*cnt;
io[cnt] = -;
}
void pushup(int rt)
{
sum[rt] = sum[rt<<] + sum[rt<<|];
flag[rt] = flag[rt<<] + flag[rt<<|];
}
void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt<<] += lazy[rt];
lazy[rt<<|]+= lazy[rt];
sum[rt<<] += flag[rt<<] * lazy[rt];
sum[rt<<|] += flag[rt<<|]*lazy[rt];
lazy[rt] = ;
}
}
void build(int rt,int l,int r)
{
if(l==r)
{
sum[rt] = seg[l];
if(io[l]==)flag[rt] = ;
else flag[rt] = -;
return ;
}
int mid = (l+r)>>;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
pushup(rt);
}
void update_one(int pos,int d,int l,int r,int rt)//单点更新;
{
if(l == r)
{
if(flag[rt] == )
sum[rt] += d;
else sum[rt] -= d;
return;
}
pushdown(rt);
int mid = (l+r)>>;
if(pos<=mid) update_one(pos,d,l,mid,rt<<);
else update_one(pos,d,mid+,r,rt<<|);
pushup(rt);
}
void update_d(int L,int R,int d,int l,int r,int rt)//区间更新;
{
if(l >= L && R >= r)
{
sum[rt] += flag[rt]*d;
lazy[rt] += d;
return;
}
pushdown(rt);
int mid = (l+r)>>;
if(L<=mid) update_d(L,R,d,l,mid,rt<<);
if(R>mid) update_d(L,R,d,mid+,r,rt<<|);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)//区间查询
{
if(l>=L&&r<=R)
{
return sum[rt];
}
int mid = (l+r)>>;
ll res = ;
pushdown(rt);
if(mid>=L)res += query(L,R,l,mid,rt<<);
if(mid<R)res +=query(L,R,mid+,r,rt<<|);
return res;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=; i<=n;i++)
{
scanf("%lld" ,&a[i]);
} for(int i=; i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
mp[v].pb(u);
mp[u].pb(v);
}
dfs(,);
build(,,*n);
for(int i= ;i <= m; i++)
{
int op,x,val;
scanf("%d", &op);
if(op==) {
scanf("%d%d",&x,&val);
update_one(in[x],val,,*n,);
update_one(out[x],val,,*n,);
}
else if(op==) {
scanf("%d%d",&x,&val);
update_d(in[x],out[x],val,,*n,);
}
else if(op==) {
scanf("%d",&x);
printf("%lld\n",query(,in[x],,*n,));
}
}
return ;
}

BZOJ4034 [HAOI2015]树上操作+DFS序+线段树的更多相关文章

  1. [bzoj3306]树——树上倍增+dfs序+线段树

    Brief Description 您需要写一种数据结构,支持: 更改一个点的点权 求一个子树的最小点权 换根 Algorithm Design 我们先忽略第三个要求. 看到要求子树的最小点权,我们想 ...

  2. ACM-ICPC 2018 沈阳赛区网络预赛 J. Ka Chang(树上分块+dfs序+线段树)

    题意 链接:https://nanti.jisuanke.com/t/A1998 给出一个有根树(根是1),有n个结点.初始的时候每个结点的值都是0.下面有q个操作,操作有两种,操作1.将深度为L(根 ...

  3. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  4. [luoguP3178] [HAOI2015]树上操作(dfs序 + 线段树 || 树链剖分)

    传送门 树链剖分固然可以搞. 但还有另一种做法,可以看出,增加一个节点的权值会对以它为根的整棵子树都有影响,相当于给整棵子树增加一个值. 而给以某一节点 x 为根的子树增加一个权值也会影响当前子树,节 ...

  5. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  6. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

  7. BZOJ1103 [POI2007]大都市meg dfs序 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1103 题意概括 一棵树上,一开始所有的边权值为1,我们要支持两种操作: 1. 修改某一条边的权值为 ...

  8. Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  9. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

随机推荐

  1. 【iOS】Xcode 离线文档

    Xcode 本身下载太慢…… Apple 官方文档地址:https://developer.apple.com/library/downloads/docset-index.dvtdownloadab ...

  2. 【iOS】iOS Error Domain=NSCocoaErrorDomain Code=3840 "未能完成操作。(“Cocoa”错误 3840。)"

    昨天遇到的这个问题,详细信息: ----->类和方法__25+[Manager noticeRequest:]_block_invoke399----->错误信息Error Domain= ...

  3. 又一个轮子--QMapper

    1 前言 我喜欢造轮子,一是造的时候就是深刻学习的时候,二是造着造着,说不定某天比世面上的其它轮子都要好呢.比如造过Networksocket,也造过WebApiClient,现在我也要造一个Mapp ...

  4. Python基础总结之认识lambda函数、map函数、filter() 函数。第十二天开始(新手可相互督促)

    今天周日,白天在学习,晚上更新一些笔记,希望对大家能更好的理解.学习python~ lambda函数,也就是大家说的匿名函数.它没有具体的名称,也可以叫做一句话函数,我觉得也不过分,大家看下代码,来体 ...

  5. Docker系列开篇之Virtual Machine VS Container(一)

    前言 本节开始我们正式进入Docker系列,网上关于Docker相关文章如数家珍,写博客至今,我也一直在朝着如何写出通俗易懂且不枯燥的文章这个目标前进,喃喃自语的同时也希望看到文章的童鞋能明白我在讲什 ...

  6. 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/NlOn7er0ixY1HO40dq5Gag作者:孔垂亮 目录 一.背景二.Monorepo vs M ...

  7. ASP.NET Core 框架本质学习

    本文作为学习过程中的一个记录. 学习文章地址: https://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html 一. ASP.N ...

  8. 三层架构(MVC)实现简单登陆注册验证(含验证码)

    前言在我的上一篇微博里我已经提出了登陆的方法,当时我采取的是纯servlet方式,因为当时刚接触到servlet,正好网上没有这方面的全面讲解,所以我就发飙了.不过在现实生产中我们大多采用的三层架构. ...

  9. 从零开始学习springboot之热部署的配置

    各位看官大家好,博主之前因为毕业设计以及毕业旅游耽搁了好长一段时间没有更新博客了,从今天起又会慢慢开始学习啦. 今天主要是来学习springboot热部署的配置. 一. 热部署 我们通常在修改某些文件 ...

  10. 一段代码分清global和nonlocal

    废话不多说,直接代码啊~~~ a=999 b=99999 def test1(): a=888 b=88888 print('a={}'.format(a)) print('b={}'.format( ...