Vasya and a Tree CodeForces - 1076E(线段树+dfs)
I - Vasya and a Tree
其实参考完别人的思路,写完程序交上去,还是没理解啥意思。。昨晚再仔细想了想。终于弄明白了(有可能不对
题意是有一棵树n个点,初始时候每个点权值都为0,m次修改,对v的叶子节点且距离小于d的都加上x
也就是v以下d层包括v自身都加上x 问最后每个点的权值
现在一想 用线段树来维护就是很自然的事了
但是要维护什么值呢
维护的就是某个深度上增加的值
先更新 后回溯取消更新
详见代码注释
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#define lp p<<1
#define rp p<<1|1
#define ll long long
using namespace std;
const int maxn = 3e5 + ;
typedef pair<int, int> P;
int n, m;
int tot, head[maxn];
struct Edge{ int to, next; }edge[maxn<<];
vector<P> vec[maxn];
ll a[maxn<<], lazy[maxn<<], res[maxn];
inline void addedge(int u, int v) {
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
inline void pushup(int p) {
a[p] = a[lp] + a[rp];
}
inline void pushdown(int p, int llen, int rlen) {
if (lazy[p]) {
lazy[lp] += lazy[p];
lazy[rp] += lazy[p];
a[lp] += lazy[p] * llen;
a[rp] += lazy[p] * rlen;
lazy[p] = ;
}
}
void build(int p, int l, int r) {
a[p] = lazy[p] = ;
if (l == r) return;
int mid = l + r >> ;
build(lp, l, mid);
build(rp, mid + , r);
pushup(p);
}
void update(int p, int l, int r, int x, int y, int z) {
if (x <= l && y >= r) {
a[p] += 1LL * z * (r - l + );
lazy[p] += z;
return;
}
int mid = l + r >> ;
pushdown(p, mid - l + , r - mid);
if (x <= mid) update(lp, l, mid, x, y, z);
if (y > mid) update(rp, mid + , r, x, y, z);
pushup(p);
}
ll query(int p, int l, int r, int u) {
if (l == r) return a[p];
int mid = l + r >> ;
pushdown(p, mid - l + , r - mid);
if (u <= mid) return query(lp, l, mid, u);
return query(rp, mid + , r, u);
}
//截至这里 应该都是线段树的基本操作 没啥好说的
void dfs(int f, int u, int d) {
for (int i = , sz = vec[u].size(); i < sz; i++) {
// 因为线段树记录的是深度 所以就可以把当前结点以及深度差为k的全部更新一遍
update(, , n, d, min(n, d + vec[u][i].first), vec[u][i].second);
}
//接下来dfs遍历的时候的update操作不会影响到父节点了 所以可以直接query得到答案
res[u] = query(, , n, d);
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v == f) continue;
// 深度位置是共享的 比如 1既连接2又连接3 上面更新了深度为1,2的 在线段树上 2代表的就是2和3的权值
dfs(u, v, d + );
}
for (int i = ; i < vec[u].size(); i++) {
//回溯取消标记
update(, , n, d, min(n, d + vec[u][i].first), -vec[u][i].second);
}
}
int main() {
scanf("%d", &n);
tot = ;
memset(head, -, sizeof(head));
for (int i = , u, v; i < n - ; i++) {
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
scanf("%d", &m);
while (m--) {
int v, d, x;
scanf("%d%d%d", &v, &d, &x);
vec[v].push_back(make_pair(d, x));
}
dfs(-, , );
for (int i = ; i <= n; i++) {
printf("%I64d", res[i]);
if (i == n) puts("");
else putchar(' ');
}
return ;
}
Vasya and a Tree CodeForces - 1076E(线段树+dfs)的更多相关文章
- Vasya and a Tree CodeForces - 1076E (线段树 + dfs)
题面 Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 writ ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset
Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...
- Alyona and a tree CodeForces - 739B (线段树合并)
大意: 给定有根树, 每个点$x$有权值$a_x$, 对于每个点$x$, 求出$x$子树内所有点$y$, 需要满足$dist(x,y)<=a_y$. 刚开始想错了, 直接打线段树合并了..... ...
- Vasya and a Tree CodeForces - 1076E
很好的思维 转化为对树上的深度差分 回朔的思想 对查询离线 #include<iostream> #include<cstdio> #include<cmath> ...
- Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论
Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...
- 2016湖南省赛 I Tree Intersection(线段树合并,树链剖分)
2016湖南省赛 I Tree Intersection(线段树合并,树链剖分) 传送门:https://ac.nowcoder.com/acm/contest/1112/I 题意: 给你一个n个结点 ...
- CF620E New Year Tree 状压+线段树(+dfs序?)
借用学长的活:60种颜色是突破口(我咋不知道QAQ) 好像这几道都是线段树+dfs序??于是你可以把60种颜色压进一个long long 里,然后向上合并的时候与一下(太妙了~) 所以记得开long ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
随机推荐
- redis学习(一)——redis介绍及安装
一.redis简介 redis是一个高性能的key-value非关系数据库,它可以存键(key)与5种不同类型的值(value)之间的映射(mapping),支持存储的value类型包括:String ...
- nginx 配sorry page - error page
include conf.d/*.conf; server { listen 9999; server_name 127.0.0.1; location / { root html; index er ...
- 【原创】jssh linux scp ssh 免密登录开源工具
项目名 JSSH git地址: https://gitee.com/chejiangyi/jssh 项目介绍 linux scp(文件上传,下载) shell命令的java ssh jar和linux ...
- input表单提交完毕,返回重新填入有黄色背景,和 历史记录 清除
<input autocomplete="value"> // 添加这个属性,可以解决然后添加一个css input:-webkit-autofill {box-sha ...
- 如何编写.NET Core Global Tools (附两个案例)
一.什么是 .NET Core Global Tools 2018年5月31日(北京时间)微软发布了 .NET Core 2.1 正式版,.NET Core 2.1 为我们带来了一个新的特性:.NET ...
- Visual studio 2015 Community 安装过程中遇到问题的终极解决
早就有给自己电脑升级VS的想法,可是安装过程并不顺利,一直拖到现在,昨天下定决心,把遇到的问题一个个解决,终于安装成功了,将安装过程中遇到的问题和解决方法记录一下. 需要说明一下的是,不同的电脑环境可 ...
- C#里面滥用String造成的性能问题
前两天给我们的json写一个解析函数, 之前用的正宗的json parser, 支持完整的json特性. 但是实际上我们用到特性, 只有key-value的映射, value的类型只有数字和字符串两种 ...
- Linux安装Apache常见报错(一)
启动Apache提示报错:Could not reliably determine the server's fully qualified domain name, using localhost, ...
- Python里面如何拷贝一个对象
1.赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个. In [168]: a Out[168]: [1, 2, 3] In [169]: b=a In [170]: a ...
- PlainElastic.Net
PlainElastic.Net PlainElastic.Net The really plain Elastic Search .Net client. Idea Installation How ...