CF E. Vasya and a Tree】 dfs+树状数组(给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值)
题意:
给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值
首先要明确两件事情
性质1.每个人的操作只会影响到他的子孙(包括自己) 性质1.每个人的操作只会影响到他的子孙(包括自己)性质1.每个人的操作只会影响到他的子孙(包括自己)
性质2.每个人只会被他祖先的操作所影响(包括自己) 性质2.每个人只会被他祖先的操作所影响(包括自己)性质2.每个人只会被他祖先的操作所影响(包括自己)
也就是说,如果我们能在访问到某个节点时,统计出所有影响到该节点的祖先操作 也就是说,如果我们能在访问到某个节点时,统计出所有影响到该节点的祖先操作也就是说,如果我们能在访问到某个节点时,统计出所有影响到该节点的祖先操作
就可以统计出这个节点的最终权值 就可以统计出这个节点的最终权值就可以统计出这个节点的最终权值
而对于每个操作,我们只要用一个dep数组保存每个深度被增加的值 而对于每个操作,我们只要用一个dep数组保存每个深度被增加的值而对于每个操作,我们只要用一个dep数组保存每个深度被增加的值
所有深度大于当前节点的操作都会影响到当前节点,如果用线段树就是一个区间求和问题 所有深度大于当前节点的操作都会影响到当前节点,如果用线段树就是一个区间求和问题所有深度大于当前节点的操作都会影响到当前节点,如果用线段树就是一个区间求和问题
为了减少代码量我们用树状数组,更新时只在本次操作的最深的深度更新 为了减少代码量我们用树状数组,更新时只在本次操作的最深的深度更新为了减少代码量我们用树状数组,更新时只在本次操作的最深的深度更新
这样求一个1−maxdep的前缀和就是所有更新了根节点的操作 这样求一个1-maxdep的前缀和就是所有更新了根节点的操作这样求一个1−maxdep的前缀和就是所有更新了根节点的操作
在求一个1−(nowdep−1)的前缀和就是所有不包含当前节点的操作 在求一个1-(nowdep-1)的前缀和就是所有不包含当前节点的操作在求一个1−(nowdep−1)的前缀和就是所有不包含当前节点的操作
两个前缀和相减就是当前节点被更新的值 两个前缀和相减就是当前节点被更新的值两个前缀和相减就是当前节点被更新的值
为了保证每个操作只影响自己子树内的节点,在dfs退出子树时 为了保证每个操作只影响自己子树内的节点,在dfs退出子树时为了保证每个操作只影响自己子树内的节点,在dfs退出子树时
要将当前根节点的所有修改值还原 要将当前根节点的所有修改值还原要将当前根节点的所有修改值还原
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 3e5+;
int n,m;
ll tree[maxn],ans[maxn];
vector<int> G[maxn],D[maxn],X[maxn];
void add(int x,int val)
{
while(x<=n)
{
tree[x]+=val;
x=x+(x&-x);
}
}
ll sum(int x)
{
ll ans=;
while(x)
{
ans+=tree[x];
x=x-(x&-x);
}
return ans;
}
void dfs(int x,int fa,int dep)
{
for(int i=;i<D[x].size();i++)
{
add(min(D[x][i]+dep,n),X[x][i]);//进子树之前更新
}
ans[x]=sum(n)-sum(dep-);//树状数组变区间查询为两个前缀和相减
//由于性质2,所以在这个地方就可以直接算出当前节点的最终答案
for(int i=;i<G[x].size();i++)
{
if(G[x][i]==fa) continue;
dfs(G[x][i],x,dep+);
}
for(int i=;i<D[x].size();i++)
{
add(min(D[x][i]+dep,n),-X[x][i]);//出子树之后还原
}
}
int main()
{
int x,y,z;
scanf("%d",&n);
for(int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
D[x].push_back(y);
X[x].push_back(z);
}
dfs(,,);
for(int i=;i<=n;i++)
{
printf("%lld ",ans[i]);
}
return ;
}
CF E. Vasya and a Tree】 dfs+树状数组(给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值)的更多相关文章
- 【树链剖分】【树状数组】【最近公共祖先】【块状树】bzoj3631 [JLOI2014]松鼠的新家
裸题,树状数组区间修改+单点查询.当然要稍微讨论一下链的左右端点是否修改的情况咯. #include<cstdio> #include<algorithm> #include& ...
- 【树状数组】【P3372】 【模板】线段树 1
Description 给定一个长度为 \(n\) 的序列,有 \(m\) 次操作,要求支持区间加和区间求和. Limitation \(1 \leq n,~m \leq 10^5\) 序列元素值域始 ...
- 【树状数组区间修改区间求和】codevs 1082 线段树练习 3
http://codevs.cn/problem/1082/ [AC] #include<bits/stdc++.h> using namespace std; typedef long ...
- hdu 5877 Weak Pair dfs序+树状数组+离散化
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Prob ...
- POJ3321Apple Tree Dfs序 树状数组
出自——博客园-zhouzhendong ~去博客园看该题解~ 题目 POJ3321 Apple Tree 题意概括 有一颗01树,以结点1为树根,一开始所有的结点权值都是1,有两种操作: 1.改变其 ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组 异或
http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...
- Codeforces 570D TREE REQUESTS dfs序+树状数组
链接 题解链接:点击打开链接 题意: 给定n个点的树.m个询问 以下n-1个数给出每一个点的父节点,1是root 每一个点有一个字母 以下n个小写字母给出每一个点的字母. 以下m行给出询问: 询问形如 ...
- POJ 3321 Apple Tree 树状数组+DFS
题意:一棵苹果树有n个结点,编号从1到n,根结点永远是1.该树有n-1条树枝,每条树枝连接两个结点.已知苹果只会结在树的结点处,而且每个结点最多只能结1个苹果.初始时每个结点处都有1个苹果.树的主人接 ...
- HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: weak pair的要求: 1.u是v的祖先(注意不一定是父亲) 2.val[u]*va ...
- [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)
[BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
随机推荐
- 【WebRTC】简介
WebRTC 名称源自网页实时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API.它于2011年6月1日开源并在Goog ...
- C++知识点总结(5)
1.为何静态成员函数不能调用非静态成员函数 静态成员函数可以不需要类的实例就直接使用,非静态的成员函数很可能用到一些成员变量,而成员变量的创建和初始化是在创建了类的实例时在构造函数调用的时候才进行的. ...
- sys添加调用模块的路径;遍历可以调用模块的路径
import sys sys.path.append("D:") for i in sys.path: print(i)
- global作用域
1 global在函数内部 $somevar=15; function addit () { GLOBAL $somevar; $somevar++ ; echo "somevar is ...
- Easyui datebox单击文本框显示日期选择 eayui版本1.5.4.1
Easyui默认是点击文本框后面的图标显示日期,体验很不好,所以我想单击文本框就显示日期选择框,网上很多版本是1.3,1.4的,于是自己就比葫芦画瓢改了一个1.5.4.1的版本. 我参考了网上这个帖子 ...
- Luogu 2467 [SDOI2010]地精部落
挺有意思的题. 优质题解: https://www.luogu.org/blog/user55639/solution-p2467 题意为求长度为n,取值为$[1, n]$的波动序列的个数. 首先需要 ...
- SQL Server相关知识和经验的碎片化记录
1.在向服务器发送请求时发生传输级错误 在向服务器发送请求时发生传输级错误. (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接.) ---> Sy ...
- 数据结构 nxd(顺序对)
数据结构 nxd(顺序对) 问题描述 给定 n 个数 a1,a2,...,an,求满足条件的(i,j)数量: i<j 且 a[i]<a[j] ★数据输入输入第一行为一个正整数 n.第二行为 ...
- C# winForm 开机自动启动 并启动后最小化到任务栏 右侧通知栏并交互操作
//设置自动启动 string path = Application.StartupPath; SettingHel.SetAutoRun(path +@"\MostImpressive.D ...
- es6学习总结一
一.let与var 的区别 (1).作用域: let什么的变量在块级作用域内有效,而var声明则在全局作用内有效 (2).变量提升: let声明的变量不存在变量提升,即一定要在声明之后才能调用,否则就 ...