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 ...
随机推荐
- Python这么强大, 怎样才能快速入坑?
作为一种年轻的编程语言,Python为何能在短短几年的时间内就以迅雷不及掩耳之势驰骋编程界?答案很简单,在人工智能时代,AlphaGo 都在使用的 Python语言,是最接近 AI 的编程语言. 随着 ...
- Java多线程(三)—— synchronized关键字详解
一.多线程的同步 1.为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资 ...
- 环境部署(三):Linux下安装Git
Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理,是目前使用范围最广的版本管理工具. 这篇博客,介绍下Linux下安装Git的步骤,仅供参考,当然,还是yum安装 ...
- iOS开发之CoreImage
CoreImage是iOS中的一个图像处理框架,提供了强大高效的图像处理功能,可以通过调用简单的API来使用框架所带的各种滤镜对图像进行处理. CoreImgae的三个重要组成部分:1.CIFiter ...
- BZOJ3561 DZY Loves Math VI 莫比乌斯反演
传送门 看到\(gcd\)相关先推式子(默认\(N \leq M\)): \(\begin{align*} \sum\limits_{i=1}^N \sum\limits_{j=1}^M (lcm(i ...
- linux服务器负载问题排查
目录 一.CPU和内存问题 top命令 vmstat命令 free命令 二.磁盘问题 iostat命令 iotop命令 du和df命令 三.网络问题 nload命令 nethogs tcpdump 最 ...
- DOM(一)
DOM可以将任何HMLT或XML文档描绘成一个由多层节点构成的结构,节点氛围几种不同的类型,每种类型分别表示文档中不同的信息及标记,每个节点都拥有各自的特点.数据和方法. Node类型 DOM1级定义 ...
- Eclipse MAT内存分析工具(Memory Analyzer Tool)
MAT内存分析工具 MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器.可以用于查找内存泄露以及查看内存消耗情况.MAT是基于Eclipse开发的,是一款免费的性能分 ...
- Spring MVC数据绑定入门总结
1.基本类型 基本类型参数不可为空 正例:http://localhost:8080/demo/he?id=2 反例:http://localhost:8080/demo/he?id=(报400错误) ...
- IT江湖--这个冬天注定横尸遍野
今年江湖大事繁起,又至寒冬,冻的不仅是温度,更是人心. 这两天上班途中看到多个公众号和媒体发了很多 "XXX公司裁员50%" 等等诸如此类的文章,也真是撼动人心.寒冬,比以往来的更 ...