题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。维尼是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

输入

第一行一个整数n,表示房间个数
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

输出

一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。

样例输入

5
1 4 5 3 2
1 2
2 4
2 3
4 5

样例输出

1
2
1
2
1

提示

2<= n <=300000


题解

很简单的一道题,用了下差分数组。

先求出两个点的最近公共祖先(这里使用树链剖分,细节少),然后打标记,不难理解。

最后把子节点的标记累加到根节点即可。

注意每次走的路径都有重复的,所以算完后还要减掉一遍。

#include <stdio.h>
#include <algorithm>
using namespace std;
int a[300001] , head[300001] , to[600001] , next[600001] , cnt , fa[300001] , deep[300001] , si[300001] , bl[300001] , tot , s[300001] , q[300001];
void add(int x , int y)
{
to[++cnt] = y;
next[cnt] = head[x];
head[x] = cnt;
}
void dfs1(int x)
{
int i , y;
si[x] = 1;
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(y != fa[x])
{
fa[y] = x;
deep[y] = deep[x] + 1;
dfs1(y);
si[x] += si[y];
}
}
}
void dfs2(int x , int c)
{
int k = 0 , i , y;
q[++tot] = x;
bl[x] = c;
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(y != fa[x] && si[y] > si[k])
k = y;
}
if(k != 0)
{
dfs2(k , c);
for(i = head[x] ; i ; i = next[i])
{
y = to[i];
if(y != fa[x] && y != k)
dfs2(y , y);
}
}
}
int lca(int x , int y)
{
while(bl[x] != bl[y])
{
if(deep[bl[x]] < deep[bl[y]])
swap(x , y);
x = fa[bl[x]];
}
if(deep[x] < deep[y])
return x;
return y;
}
int main()
{
int n , i , x , y , k;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
scanf("%d" , &a[i]);
for(i = 1 ; i < n ; i ++ )
{
scanf("%d%d" , &x , &y);
add(x , y);
add(y , x);
}
dfs1(1);
dfs2(1 , 1);
for(i = 2 ; i <= n ; i ++ )
{
k = lca(a[i] , a[i - 1]);
s[a[i]] ++ ;
s[a[i - 1]] ++ ;
s[k] -- ;
s[fa[k]] -- ;
}
for(i = n ; i >= 2 ; i -- )
s[fa[q[i]]] += s[q[i]];
for(i = 2 ; i <= n ; i ++ )
s[a[i]] -- ;
for(i = 1 ; i <= n ; i ++ )
printf("%d\n" , s[i]);
return 0;
}

【bzoj3631】[JLOI2014]松鼠的新家的更多相关文章

  1. [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2350  Solved: 1212[Submit][Sta ...

  2. BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】

    题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松鼠想 ...

  3. [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)

    题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...

  4. [BZOJ3631][JLOI2014]松鼠的新家(树链剖分)

    [BZOJ3631] 树剖模板题了, Code #include <cstdio> #include <algorithm> #define MID int mid=(l+r) ...

  5. bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)

    题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...

  6. BZOJ3631: [JLOI2014]松鼠的新家

    传送门 树上的差分优化,很简单的一道题,应该属于NOIP2015TGD2T3的子问题. //BZOJ 3631 //by Cydiater //2016.10.25 #include <iost ...

  7. BZOJ3631[JLOI2014]松鼠的新家 题解

    题目大意: 给你一棵树,要从编号为a[1]的节点走到编号为a[2]的节点再走到编号为a[3]的节点……一直走到编号为a[n]的节点.问每个节点最少访问多少次. 思路: 将其进行轻重链剖分,则从a[i] ...

  8. bzoj3631[JLOI2014 松鼠的新家 倍增lca+差分

    裸的树上差分+倍增lca 每次从起点到终点左闭右开,这就有一个小技巧,要找到右端点向左端点走的第一步,然后差分就好了 #include<cstdio> #include<cstrin ...

  9. 【树链剖分】【树状数组】【最近公共祖先】【块状树】bzoj3631 [JLOI2014]松鼠的新家

    裸题,树状数组区间修改+单点查询.当然要稍微讨论一下链的左右端点是否修改的情况咯. #include<cstdio> #include<algorithm> #include& ...

  10. bzoj3631 [JLOI2014]松鼠的新家——树上差分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 树上差分:注意路径的结尾被多算了一次,最后要减去(不能提前减). 代码如下: #inc ...

随机推荐

  1. 重新认识unicode和utf8编码

    重新认识unicode和utf8编码 直到今天,准确的说是刚才,我才知道UTF-8编码和Unicode编码是不一样的,是有区别的囧 他们之间是有一定的联系的,看看他们的区别: UTF-8的长度是不一定 ...

  2. CF 702B Powers of Two(暴力)

    题目链接: 传送门 Devu and Partitioning of the Array time limit per test:3 second     memory limit per test: ...

  3. 通往WinDbg的捷径(二)

    原文:http://www.debuginfo.com/articles/easywindbg2.html译者:arhat时间:2006年4月14日关键词:CDB WinDbg 保存 dumps 在我 ...

  4. 翻译:通往WinDbg的捷径(一)

    原文:http://www.debuginfo.com/articles/easywindbg.html译者:arhat时间:2006年4月13日关键词:CDB WinDbg 导言你钟情什么样的调试器 ...

  5. 用LinkedList模拟栈数据结构的集合

    用Eclipse软件进行操作    有2种方法,左边为第一种,右边为第二种 创建class为MyStack 代码实现: package cn_LinkedList;   import java.uti ...

  6. string find

    string类的查找函数: ) const;//从pos开始查找字符c在当前字符串的位置 ) const;//从pos开始查找字符串s在当前串中的位置 int find(const char *s, ...

  7. MathML + MathJax在网页中插入公式

    http://www.mathjax.org/download/ http://www.w3.org/Math/Software/mathml_software_cat_editors.html ht ...

  8. Jquerymobile随笔

    fixed <div data-role="header" data-position="fixed"> <h1>欢迎访问我的主页< ...

  9. PetaPoco 使用总结(二)

    接着上一篇,上一篇主要介绍了PetaPoco 基本情况,优缺点和基本的查询功能,所以这篇主要介绍的是PetaPoco 的增,删,改等功能.PetaPoco提供了完整的增,删,改,查功能.是代替SqlH ...

  10. sn 密钥注册

    ::打开开发人员命令提示符输入一下内容与证书密码sn -i CanChou.snk.pfx VS_KEY_4B89A33EE2B53C07