I - Vasya and a Tree

CodeForces - 1076E

其实参考完别人的思路,写完程序交上去,还是没理解啥意思。。昨晚再仔细想了想。终于弄明白了(有可能不对

题意是有一棵树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)的更多相关文章

  1. 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 ...

  2. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  3. Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset

    Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...

  4. Alyona and a tree CodeForces - 739B (线段树合并)

    大意: 给定有根树, 每个点$x$有权值$a_x$, 对于每个点$x$, 求出$x$子树内所有点$y$, 需要满足$dist(x,y)<=a_y$. 刚开始想错了, 直接打线段树合并了..... ...

  5. Vasya and a Tree CodeForces - 1076E

    很好的思维 转化为对树上的深度差分 回朔的思想 对查询离线 #include<iostream> #include<cstdio> #include<cmath> ...

  6. Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

    Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...

  7. 2016湖南省赛 I Tree Intersection(线段树合并,树链剖分)

    2016湖南省赛 I Tree Intersection(线段树合并,树链剖分) 传送门:https://ac.nowcoder.com/acm/contest/1112/I 题意: 给你一个n个结点 ...

  8. CF620E New Year Tree 状压+线段树(+dfs序?)

    借用学长的活:60种颜色是突破口(我咋不知道QAQ) 好像这几道都是线段树+dfs序??于是你可以把60种颜色压进一个long long 里,然后向上合并的时候与一下(太妙了~) 所以记得开long ...

  9. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

随机推荐

  1. PAT A1055 The World's Richest (25 分)——排序

    Forbes magazine publishes every year its list of billionaires based on the annual ranking of the wor ...

  2. PAT A1052 Linked List Sorting (25 分)——链表,排序

    A linked list consists of a series of structures, which are not necessarily adjacent in memory. We a ...

  3. python:HTMLTestRunner测试报告优化

    之前的博客有介绍过python的单元测试框架unittest,基于其扩展的测试报告模块HTMLTestRunner,不过这个报告本身的界面看起来太丑... 趁着今天有时间,找了两个二次开发优化后的HT ...

  4. python:利用xlrd模块操作excel

    在自动化测试过程中,对测试数据的管理和维护是一个不可忽视的点.一般来说,如果测试用例数据不是太多的话,使用excel管理测试数据是个相对来说不错的选择. 这篇博客,介绍下如何利用python的xlrd ...

  5. jquery.$.ajax简单的使用

    function LoadWFS() { var viewer = new Cesium.Viewer('cesiumContainer'); $.ajax({ url: "http://l ...

  6. python实现本地图片上传到服务区

    本地图片上传到服务器,其本质上来讲,就是读取本地图片,复制到服务器,并返回服务器url 前端代码,用的form表单提交,form表单中包含两个文件选择表单元素,选择文件,点击提交按钮,提交form表单 ...

  7. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛D-80 Days--------树状数组

    题意就是说1-N个城市为一个环,最开始你手里有C块钱,问从1->N这些城市中,选择任意一个,然后按照顺序绕环一圈,进入每个城市会有a[i]元钱,出来每个城市会有b[i]个城市,问是否能保证经过每 ...

  8. 动态规划-LCS最长公共子序列

    #include<iostream> #include<cstdio> #include<cstring> #include<string> using ...

  9. 1177: LFX学橙啦!题解

    问题如下:先给你一个含有N个整数的数组数组中的每一个元素只为1或者0而N的大小为1~100你可以删除一些元素(也可以选择不删除),使剩下的数组中,没有一个元素0在1后面出现.并且要使剩下的元素的数量最 ...

  10. 同步和异步概念(由DZW前端框架引发的百度地图api无法加载问题总结)

    首先概念: 在计算机领域,同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去:异步是指进程不需要一直等下去,而是继续 ...