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的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
随机推荐
- JS中,日期对象(获取当前现在的年份,星期,时间)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Linux 压缩文件 和解压文件
.zip 解压:unzip FileName.zip 压缩:zip FileName.zip DirName .rar 解压:rar -x FileName.zip 压缩:rar -a FileNam ...
- 解决列表中增加字典覆盖之前相同key的字典
dic = {} lst = [] # 先声明一个字典和一个列表 dic['name'] = "chenrun" lst.append(dic) print(lst) dic[&q ...
- 【Boost】boost库获取格式化时间
获取时间方式 格式一:YYYYMMDD #include<iostream> #include<string> #include<boost/date_time/greg ...
- Ubuntu Java Env
From http://www.cnblogs.com/BigIdiot/archive/2012/03/26/2417547.html Java 环境变量 用户环境变量通常被存储在下面的文件中: ~ ...
- Luogu 2254 [NOI2005]瑰丽华尔兹
简单dp,设$f_{i,j,k}$表示第i个时间段,钢琴处在(j,k)位置移动距离的最大值,那么有转移 $f_{i, j, k} = max(f_{i - 1, j, k}) , f_{i, j, ...
- PersonDto中@ResourceAccess(readOnly = true)以及swagger的理解-----似懂非懂,日后消化
@JsonApiResource(type = PersonDto.RESOURCE_TYPE) @EntityMapping(entityClass = Person.class) //@Resou ...
- serializeArray()和.serialize()的区别、联系
serializeArray()和.serialize()的区别.联系 <form id='addForm' action='UserAdd.action' type='post'> ...
- 数据结构 queue
问题描述 t 个团队在餐厅前准备排队. 他们的排队规则是:初始队伍为空.一个人要排进队伍前, 先搜索队伍中是否有他的队友. 如果有, 这名成员就直接站在最后一个队友的后面,如果没有,那么这名成员只能排 ...
- Windows下启动redis错误1067:进程意外中止
已解决: 在redis-64.3.0.503文件夹下新建一个空文件夹,命名为logs,如下图所示: 最后成功了 开启服务:redis-server --service-start