题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(n\)个房间,并且有\(n-1\)根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去\(a_1\),再去\(a_2\),......,最后到\(a_n\),去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间\(a_n\)是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入格式
第一行一个整数\(n\),表示房间个数第二行\(n\)个整数,依次描述\(a_1-a_n\)
接下来\(n-1\)行,每行两个整数\(x\),\(y\),表示标号\(x\)和\(y\)的两个房间之间有树枝相连。
输出格式
一共\(n\)行,第\(i\)行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。
输入输出样例
输入 #1
5
1 4 5 3 2
1 2
2 4
2 3
4 5
输出 #1
1
2
1
2
1
说明/提示
\(2<= n <=300000\)
解析:
LCA + 树上差分
对于访问序号我们将其变成边的形式。
对于所有的的边,
我们会发现第一条和最后一条是特殊的。
第一条是两个端点都是包含的, 即在两个端点上都放糖果:[u,v]
最后一条是两个端点都不包含, 即在两个端点上不放糖果:(u,v)
其余的路径都是一样的,前一个包含,后一个不包含:[u,v)
f数组是倍增lca数组,u和v分别是一边的端点。
先看第一条边,直接进行树上差分,无特殊处理。
最后一条边,我们要进行讨论,一共有3种情况:
u != LCA && v != LCA
,那么我们要差分的边就是f[u][0]-f[v][0].
u == LCA && v != LCA
,那么我们要差分的边就是son[u]-f[v][0].
u != LCA && v == LCA
,那么我们要差分的边就是f[u][0]-son[v].
- 其余的边,也是讨论3种情况:
u != LCA && v != LCA
,那么我们要差分的边就是f[u][0]-v.
u == LCA && v != LCA
,那么我们要差分的边就是son[u]-v.
u != LCA && v == LCA
,那么我们要差分的边就是f[u][0]-v
做完这些,就是树上差分的板子了,这里就不赘述了。
#include
#include
#include
#include
#include
#include