J - Whistle's New Car Gym - 101147J

Statements

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

Input

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 ABC (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.

Output

For each test case, output a line containing n integers, the attractiveness of each city.

Example
Input
1
4
5 10 5 10
1 2 100
2 3 5
3 4 5
Output
0 2 1 0
Note

Large I/O files. Please consider using fast input/output methods.


这个题吧,一开始想的太复杂了,各种想乱搞都没有成功,尴尬。

发现树dp好像搞不了的样子。

最后的最后才发现直接按dfs序来做这个题的话,就可以维护了,因为之前的唯一问题是如何最快的找到那个点最远可以到那个点,想二分但是在树上不能二分,但现在是一条链了,所以自然可以维护的了了,然后所有的问题就解决了,之前想用线段树可是不知道哪里写残了,WA2,然后学了下这个前缀和维护的思想。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
int T,n;
LL value[maxn];

int head[maxn],_cnt;
struct Edge{
	int to,next;
	LL w;
}edge[maxn<<1];
inline init(){
	for(int i = 1; i <= n; i++)
		head[i] = -1;
	_cnt = 0;
}
inline void ADD(int u,int v,LL w){
	edge[_cnt].to = v;
	edge[_cnt].w = w;
	edge[_cnt].next = head[u];
	head[u] = _cnt++;
}
LL sum[maxn],tot;
int ans[maxn];
int id[maxn],fa[maxn];
void dfs(int now,int father){
	for(int i = head[now]; ~i; i = edge[i].next){
		int v = edge[i].to;
		if(v != father){
			fa[v] = now;
			sum[tot] = sum[tot-1]+edge[i].w;
			id[tot] = v;
			int pos = lower_bound(sum,sum+tot+1,sum[tot]-value[v])-sum;
			if(pos < tot)
				ans[now]++,ans[fa[id[pos]]]--;
			tot++;
			dfs(v,now);
			tot--;
			ans[now] += ans[v];
		}
	}
}
int main(){
	freopen("car.in","r",stdin);
	int u,v;
	LL w;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		init();
		for(int i = 1; i <= n; i++)
			scanf("%lld",&value[i]);
		for(int i = 1; i < n; i++){
			scanf("%d %d %lld",&u,&v,&w);
			ADD(u,v,w);
			ADD(v,u,w);
		}
		memset(ans,0,sizeof(ans));
		sum[0] = 0;
		id[0] = 1;
		tot = 1;
		dfs(1,1);
		for(int i = 1; i <= n; i++)
			printf("%d%c",ans[i],(i == n)?'\n':' ');
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值