Gym - 101147J Whistle's New Car 树上差分
15 seconds
512 megabytes
car.in
standard output
Whistle has bought a new car, which has an infinite fuel tank capacity.
He discovered an irregular country since it has n cities and there are exactly n - 1 roads between them, of course, all cities are connected. He is so much clever, he realized that the country is like a rooted tree of n nodes and node 1 is the root. Each city i has only one filling station by which he can fill his car's fuel tank in no more than Xi liter. Whistle liked the country very much, and he wants to know what the most attractive city in the country is. The attractiveness of the city i is defined by how much it’s reachable from other cities, in other words the attractiveness of city is the number of cities j that satisfies these condition:
- City j is in the subtree of city i (except for city i itself).
- Whistle will start at city j and will only fill his car’s fuel tank with Xj liters and never fill it again until he reach city i.
- Whistle should be able to reach city i with non-negative fuel.
He knows the length of every road and that 1 Km will take exactly 1 liter on any road.
As you know, Whistle is very clever, but he is not that good at programming, so he asked you to help him. He wants to know the attractiveness of each city, so that he can decide which city to live in.
The first line of input contains one integer T, the number of test cases.
The next line contains one integer (1 ≤ n ≤ 500, 000), The number of cities in the country.
The next line contains n integers (1 ≤ Xi ≤ 1, 000, 000, 000).
Each one of the next n - 1 line contains three integers A, B, C (1 ≤ A, B ≤ n and 1 ≤ C ≤ 1, 000, 000, 000), that means there is a road between city A and city B of length C.
For each test case, output a line containing n integers, the attractiveness of each city.
1
4
5 10 5 10
1 2 100
2 3 5
3 4 5
0 2 1 0
Large I/O files. Please consider using fast input/output methods.
设dis[i]表示从根节点1走到第 i个节点的路径长度。
那么任意的路径u-->v(前提是u是v的祖先,不然要用lca,这里不需要)可以表示为dis[v] - dis[u]
那么如果v能走回到u,则需要a[v] >= dis[v] - dis[u],即是dis[v] - a[v] <= dis[u],其中dis[v] - a[v]是一个确定值。
那么题意转换成,对于每一个节点u,有一个值dis[u],问其子树中,有多少个节点,满足dis[sonNode] - a[sonNode] <= dis[u]的。
这里可以用dfs序,然后用区间第k大的线段树或者分块、离线BIT之类的数据结构维护。
但是注意到dis[]是关于深度递增的,就是越走到下面,dis越大,也就是单调。
那么dfs的时候,用个vector记录一下路径长度和节点id。二分找到第一个祖先,使得满足dis[sonNode] - a[sonNode] <= dis[u]
那么可以知道ans[那个祖先节点 ---- 当前节点的爸爸],这条路径上的贡献都要加1
其实也就是打标记。
和一维差不多,L....R中加上1等价于sum[L] += 1, sum[R + 1] -= 1
这里一样,sum[当前节点的爸爸] += 1, sum[第一个满足的祖先的爸爸] -= 1
不能从上到下打标记,因为儿子数目不确定,而爸爸是确定的。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
struct Edge {
int u, v, tonext, len;
}e[maxn * ];
int first[maxn], num;
int a[maxn];
void addEdge(int u, int v, int w) {
++num;
e[num].u = u, e[num].v = v, e[num].len = w;
e[num].tonext = first[u];
first[u] = num;
}
int ans[maxn];
vector< pair<LL, int> > vc;
int vis[maxn], DFN;
void dfs(int cur, LL nowLen, int fa) {
ans[fa]++;
int pos = lower_bound(vc.begin(), vc.end(), make_pair(nowLen - a[cur], )) - vc.begin();
pos--; //去到第一个满足的的祖先的爸爸
if (pos >= ) {
ans[vc[pos].second]--;
}
vc.push_back(make_pair(nowLen, cur));
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (v == fa) continue;
dfs(v, nowLen + e[i].len, cur);
ans[cur] += ans[v];
}
vc.pop_back();
}
void work() {
num = ;
++DFN;
memset(first, false, sizeof first);
memset(ans, , sizeof ans);
int n;
scanf("%d", &n);
for (int i = ; i <= n; ++i) cin >> a[i];
for (int i = ; i <= n - ; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w);
addEdge(v, u, w);
}
dfs(, , );
for (int i = ; i <= n; ++i) {
printf("%d ", ans[i]);
}
printf("\n");
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
freopen("car.in", "r", stdin);
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
Gym - 101147J Whistle's New Car 树上差分的更多相关文章
- Codeforces Gym - 101147J Whistle's New Car
Discription Statements Whistle has bought a new car, which has an infinite fuel tank capacity. He di ...
- Gym 101147J Whistle's New Car(dfs)
https://vjudge.net/problem/Gym-101147J 题意: 有n个城市,每个城市有一个权值,表示在这个城市的加油站可以加多少油. 现在要计算每个城市i,有多少个城市j可以到达 ...
- 【树状数组】Gym - 101147J - Whistle's New Car
题意就是对每个点i,统计在其子树内(不含自身),且depj-depi<=xj的点有多少个. 把点分别按照dep-x和dep进行排序,离线处理, 每次把dep-x小于等于当前dep值的点插入树状数 ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- 树上差分 (瞎bb) [树上差分][LCA]
做noip2015的运输计划写了好久好久写不出来 QwQ 于是先来瞎bb一下树上差分 混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- 【NOIP2016】【LCA】【树上差分】【史诗级难度】天天爱跑步
学弟不是说要出丧题吗>>所以我就研究了1天lca又研究了1天tj然后研究了一天天天爱跑步,终于写了出来.(最后的平均用时为240ms...比学弟快了1倍...) 题意:给你颗树,然后有m个 ...
- BZOJ_4238_电压_树上差分+dfs树
BZOJ_4238_电压_树上差分+dfs树 Description 你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)” ...
随机推荐
- Java版本更新历史(ing)
历史版本特性 JDK Version 1.0 开发代号为Oak(橡树),于1996-01-23发行. JDK Version 1.1 于1997-02-19发行. 引入的新特性包括: 引入JDBC(J ...
- Swift初见
Swift基本类型 Swift的类型是在C和OC的基础上发展而来的,Int是整型:Double和Float是浮点型:Bool是布尔型:String是字符串.类似OC,Swift也提出了三个集合类型:A ...
- eslintrc.js
此插件主要就是规范前端程序员编写JS的规范,让代码看上去很优雅,也便于后期人员的重构和维护. 因为是用vue的cli搭建项目工程,使用了eslintrc.js ,但是在写JS时发现,首字母缩进一直报错 ...
- npm --- Node.js包管理器
目录 1. 安装Node.js 2. 运行npm 3. npm介绍 3.1 安装插件 3.2 更新插件 3.3 卸载插件 3.4 查看当前目录中的插件列表 4. 使用cnpm 4.1 安装 npm( ...
- Java并发之synchronized
Java多线程同步关键词是常用的多线程同步手段.它可以修饰静态类方法,实例方法,或代码块.修饰static静态方法时是对整个类加锁. 一.实现原理 在JVM中对象内存分三块区域,对象头.实例数据.对齐 ...
- Win10设置vs2010总是以管理员身份运行
有的项目用vs打开后直接运行总是要求提升权限,如下图 1.第一步(这样的方式只能是先运行vs,然后再打开项目,这样才是以管理员的身份运行的.但是如果是通过sln文件的快捷方式打开的,却不是 ...
- vuex 命名空间
默认情况下,模块内部的action mutation getter是注册在全局命名空间的,如果希望你的模块具有更高的封装度和复用性,你可以通过添加namespaced:true的方式使其成为带命名空间 ...
- [hdu2243]考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题意:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个. 解题关键:利用补集转化的思想,先求一个词根也不包含的单词个数,然后用总的减去即可.长度不超过L需要用矩阵维数增加一倍 ...
- HDOJ-2160
母猪的故事 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Junit使用注意点
注意点 1. 使用了@BeforeClass后@Ignore将会失效