XJOI 3363 树4/ Codeforces 739B Alyona and a tree(树上差分+路径倍增)
2 seconds
256 megabytes
standard input
standard output
Alyona has a tree with n vertices. The root of the tree is the vertex 1. In each vertex Alyona wrote an positive integer, in the vertex i she wrote ai. Moreover, the girl wrote a positive integer to every edge of the tree (possibly, different integers on different edges).
Let's define dist(v, u) as the sum of the integers written on the edges of the simple path from v to u.
The vertex v controls the vertex u (v ≠ u) if and only if u is in the subtree of v and dist(v, u) ≤ au.
Alyona wants to settle in some vertex. In order to do this, she wants to know for each vertex v what is the number of vertices u such that vcontrols u.
The first line contains single integer n (1 ≤ n ≤ 2·105).
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the integers written in the vertices.
The next (n - 1) lines contain two integers each. The i-th of these lines contains integers pi and wi (1 ≤ pi ≤ n, 1 ≤ wi ≤ 109) — the parent of the (i + 1)-th vertex in the tree and the number written on the edge between pi and (i + 1).
It is guaranteed that the given graph is a tree.
Print n integers — the i-th of these numbers should be equal to the number of vertices that the i-th vertex controls.
5
2 5 1 4 6
1 7
1 1
3 5
3 6
1 0 1 0 0
5
9 7 8 6 5
1 1
2 1
3 1
4 1
4 3 2 1 0
In the example test case the vertex 1 controls the vertex 3, the vertex 3 controls the vertex 5 (note that is doesn't mean the vertex 1controls the vertex 5).
题意:
给你一棵树,n个点, 以1为根,每个点有一个值,每条边有边权
我们规定假如u的子树中存在一个点v, 使得dist(u,v)<=a[v], dist(u,v)表示u 到 v的路径上的边权之和, a[v] 是v的点权
那么我们称u控制v
现在需要你算出每个点各控制了几个点
题解:
很显然被想到倍增统计路径和,然后你可以找到最远的那个被控制的点,然后该点到控制点的路径上全部加一,树上差分一下就行了
但是你A不了XJOI的,毕竟人家卡内存,所以还是去学所谓的树上二分吧,搬原题然后只改内存,这种素质我是第一次见。
代码如下:
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pii pair<int,int>
#define mp make_pair
#define int long long
using namespace std; int n,a[],fa[][],dis[][],d[],ans[];
vector<pii> g[]; void dfs(int now,int f,int dist)
{
fa[][now]=f;
dis[][now]=dist;
for(int i=;i<=;i++)
{
fa[i][now]=fa[i-][fa[i-][now]];
}
for(int i=;i<=;i++)
{
dis[i][now]=dis[i-][now]+dis[i-][fa[i-][now]];
}
for(int i=;i<g[now].size();i++)
{
if(g[now][i].first==f) continue;
dfs(g[now][i].first,now,g[now][i].second);
}
} int find(int x,int val)
{
int pos=x,nowd=;
for(int i=;i>=;i--)
{
if(dis[i][pos]+nowd<=val&&fa[i][pos])
{
nowd+=dis[i][pos];
pos=fa[i][pos];
}
}
return pos;
} void dfs2(int now,int f)
{
int pos=find(now,a[now]);
d[fa[][pos]]--;
d[fa[][now]]++;
for(int i=;i<g[now].size();i++)
{
if(g[now][i].first==f) continue;
dfs2(g[now][i].first,now);
}
} void dfs3(int now,int f)
{
ans[now]=d[now];
for(int i=;i<g[now].size();i++)
{
if(f==g[now][i].first) continue;
dfs3(g[now][i].first,now);
ans[now]+=ans[g[now][i].first];
}
} signed main()
{
scanf("%lld",&n);
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=;i<=n;i++)
{
int to,cost;
scanf("%lld%lld",&to,&cost);
g[to].push_back(mp(i,cost));
g[i].push_back(mp(to,cost));
}
dfs(,,);
dfs2(,);
dfs3(,);
for(int i=;i<=n;i++)
{
printf("%lld ",ans[i]);
}
}
XJOI 3363 树4/ Codeforces 739B Alyona and a tree(树上差分+路径倍增)的更多相关文章
- Codeforces 739B Alyona and a tree(树上路径倍增及差分)
题目链接 Alyona and a tree 比较考验我思维的一道好题. 首先,做一遍DFS预处理出$t[i][j]$和$d[i][j]$.$t[i][j]$表示从第$i$个节点到离他第$2^{j}$ ...
- CodeForces 739B Alyona and a tree (二分+树上差分)
<题目链接> 题目大意: 给定一颗带权树,树的根是1,树上每个点都有点权,并且还有边权.现在给出“控制”的定义:对一个点u,设v为其子树上的节点,且$dis(u,v)≤val[v]$,则称 ...
- XJOI3363 树3/Codeforces 682C Alyona and the Tree(dfs)
Alyona decided to go on a diet and went to the forest to get some apples. There she unexpectedly fou ...
- Codeforces E. Alyona and a tree(二分树上差分)
题目描述: Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- CodeForces 682C Alyona and the Tree (树+dfs)
Alyona and the Tree 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/C Description Alyona ...
- Codeforces Round #381 (Div. 2) D. Alyona and a tree 树上二分+前缀和思想
题目链接: http://codeforces.com/contest/740/problem/D D. Alyona and a tree time limit per test2 secondsm ...
- Codeforces 682C Alyona and the Tree (树上DFS+DP)
题目链接:http://codeforces.com/problemset/problem/682/C 题目大意:取树上任意一个点v,若点v的子树中有一个点u使得dist(v,u)>a[u]那么 ...
- Codeforces 682C Alyona and the Tree(树形DP)
题目大概说给一棵点有权.边也有权的树.一个结点v不高兴当且仅当存在一个其子树上的结点u,使得v到u路径上的边权和大于u的权值.现在要不断地删除叶子结点使得所有结点都高兴,问最少删几个叶子结点. 一开始 ...
- codeforces 682C Alyona and the Tree(DFS)
题目链接:http://codeforces.com/problemset/problem/682/C 题意:如果点v在点u的子树上且dist(u,v)>a[v]则u和其整个子树都将被删去,求被 ...
随机推荐
- C和指针 第三章--数据
简要概述: <C和指针>第三章对数据进行了描述. 其中主要讲解了---变量的三个属性:作用域.链接属性和存储类型. 这三个属性决定了该变量在“什么地方可以使用”以及“该变量的值能够保持多久 ...
- python _/__/__**__区别
"_"单下划线:"单下划线 " 开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问:不能用'fr ...
- 呕心沥血Android studio使用JNI实例
发现网上很多JNI的使用教程,也很详细,不过有的地方有些缺漏,导致很多小问题难以解决的,今天就来总结一下. 准备工作:下载NDK. 简单的说,要用到C/C++,就要用NDK.直接百度搜索然后去官网下载 ...
- [转] C#调用外部DLL
原文地址 每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍.首先,您需要了解什么是托管,什么是非托管.一般可以认为:非托管代码主要是基于win 32平台开发的DLL,ac ...
- **深入了解lambda
之前已经了解过lambda了,但是在学习了闭包之后,我们有必要在探讨一下lambda(匿名函数). 匿名函数本质上就是一个函数,它所抽象出来的东西是一组运算. 它的使用场景就是:你在某处就真的只需要使 ...
- Oracle的Spool导出数据
出自:http://wallimn.iteye.com/blog/472182 实践 只能在一个终端上的一个窗口中进行操作 第一步:连接oracle数据库 sqlplus qkp/mm_eft ...
- shell 中可以for 循环的时间加减日期格式
..};do # LAST_HOUR=`date -d '-${num} hour' +%H` 不可for循环,报格式错误 LAST_HOUR=`date "+%H" -d -${ ...
- BUI 框架使用指南
指南说明:只适用于对框架的剥离 如果不需要剥离则原来的东西直接粘贴就行 在主界面中使用时需要加入一下引用bui.js jquery.js config.js 末尾的文件 BUI.use(位置1, fu ...
- centos7 vnc server
yum -y install vnc *vnc-server* vncserver vncserver :2 vncserver -geometry 1900x1024 =============== ...
- c# vs c++
[c# vs c++] 1.在 C++ 中,类和结构实际上是相同的,而在 C# 中,它们很不一样.C# 类可以实现任意数量的接口,但只能从一个基类继承.而且,C# Struct不支持继承,也不支持显式 ...