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 ...
随机推荐
- Linux 内核协议栈 学习资料
终极资料 1.<Understanding Linux Network Internals> 2.<TCP/IP Architecture, Design and Implement ...
- CentOS下安装PHP
今天終於進行了第三次的在linux下的php安裝,在安裝之前我進行了網站訪問測試. 第一步,先查看mysql.apache這兩項系統服務是否已經自動啟動了,chkconfig –list mysql. ...
- Python从菜鸟到高手(8):print函数、赋值与代码块
1.神奇的print函数 print函数相信读者一定对它不陌生,因为在前面的章节,几乎每个例子都使用了print函数,这个函数的功能就是在控制台输出文本.不过print在输出文本时还可以进行一些设 ...
- 来,看看MySQL 5.6, 5.7, 8.0的新特性
对于MySQL的历史,相信很多人早已耳熟能详,这里就不要赘述.下面仅从产品特性的角度梳理其发展过程中的里程碑事件. 1995年,MySQL 1.0发布,仅供内部使用. 1996年,MySQL 3.11 ...
- POST BOY : Restful API 调试工具
在使用asp.net webapi开发中,一般情况下会使用一些工具来模拟请求. 其中有一款chrome浏览器插件POST MAN比较不错. 但是由于国内google服务使用不稳定,所以我自己写了一个简 ...
- matplot绘图基本使用
先看一个最简单的例子 import matplotlib.pyplot as plt plt.figure() plt.subplot(211) plt.plot([1,2,3], color=''r ...
- c++继承实例
#include <iostream> #include <vector> #include <string> using namespace std; class ...
- 使用jmeter来发送json/gzip格式数据 --------笔记
一.使用jmeter来发送gzip数据 有时候我们需要模拟在客户端将数据压缩后, 发送(post)到服务器端. 通常这种情况,会发生在移动终端上. 这样做的好处, 是可以节省流量. 当然, 服务器返 ...
- <c:forEach varStatus="status">中 varStatus的作用
varStatus是<c:forEach>jstl循环标签的一个属性,varStatus属性. varStatus=“status”事实上定义了一个status名的对象作为varStatu ...
- 配置router列表
import Vue from "vue"; import VueRouter from 'vue-router'; import Star from '../components ...