Description

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

松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

Input

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

Output

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

Sample Input

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

Sample Output

1
2
1
2
1

Hint

2<= n <=300000

题解

裸的树上差分。

我们将一条路径如$u->v$,

我们需要将标记数组:

$$cnt[u]++,cnt[v]++,cnt[lca(u,v)]--,cnt[fa[lca(u,v)][0]]--$$

最后上传标记即可,正确性可以画图推一下。

但注意由于这样做会将每个点重复计算一次(上一条路径的结尾,这一条路径的起始)

我们需要将每个点点权再$-1$,

注意由于第一条路径起始点是要计算的,我们还要加回来。

 #include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define Max(a,b) ((a)>(b) ? (a):(b))
#define Min(a,b) ((a)<(b) ? (a):(b))
using namespace std;
const int N=; int n,u,v,lim;
struct tt
{
int to,next;
}edge[N*+];
int path[N+],top;
void Add(int u,int v);
int a[N+]; int dep[N+],fa[N+][];
void Dfs(int r,int depth);
void RMQ();
int lca(int a,int b); int cnt[N+];
void Dfs2(int r); int main()
{
scanf("%d",&n);
lim=log(n)/log();
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<n;i++)
{
   scanf("%d%d",&u,&v);
   Add(u,v);
  Add(v,u);
}
Dfs(,);
RMQ();
for (int i=;i<n;i++)
{
  int w=lca(a[i],a[i+]);
  cnt[a[i]]++,cnt[a[i+]]++,cnt[w]--,cnt[fa[w][]]--;
}
Dfs2();
cnt[a[]]++;
for (int i=;i<=n;i++) printf("%d\n",cnt[i]-);
return ;
} void Add(int u,int v)
{
edge[++top].to=v;
edge[top].next=path[u];
path[u]=top;
}
void Dfs(int r,int depth)
{
dep[r]=depth;
for (int i=path[r];i;i=edge[i].next)
   if (!dep[edge[i].to])
   {
   fa[edge[i].to][]=r;
   Dfs(edge[i].to,depth+);
  }
}
void RMQ()
{
for (int t=;t<=lim;t++)
   for (int i=;i<=n;i++)
   fa[i][t]=fa[fa[i][t-]][t-];
}
int lca(int a,int b)
{
if (dep[a]<dep[b]) swap(a,b);
for (int i=lim;i>=;i--) if (dep[fa[a][i]]>=dep[b]) a=fa[a][i];
if (a!=b)
{
   for (int i=lim;i>=;i--) if (fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];
   a=fa[a][],b=fa[b][];
}
return a;
}
void Dfs2(int r)
{
for (int i=path[r];i;i=edge[i].next)
if (edge[i].to!=fa[r][])
{
Dfs2(edge[i].to);
cnt[r]+=cnt[edge[i].to];
}
}

[JLOI 2014]松鼠的新家的更多相关文章

  1. 洛谷P3258 [JLOI]2014松鼠的新家

    题目 树上差分 树上点差分,注意会出现路径端点多记录的情况,这时需要在最后输出的时候输出子树的差分数组的和-1,而不是在处理原数据的时候减1.并且a[n]不需要糖果,最后也减去就行. #include ...

  2. BZOJ 3631 【JLOI2014】 松鼠的新家

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

  3. 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1231  Solved: 620[Submit][Stat ...

  4. 【bzoj3631】[JLOI2014]松鼠的新家

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

  5. BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )

    裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...

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

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 707  Solved: 342[Submit][Statu ...

  7. [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)

    今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...

  8. [JLOI2014] 松鼠的新家

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

  9. 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)

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

随机推荐

  1. hibernate框架学习笔记3:API详解

    Configuration对象: package api; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configur ...

  2. The sum of numbers form 0 to n.(20.9.2017)

    #include <stdio.h> int main() { int a,b,sum; printf("输入一个数字: "); scanf("%d" ...

  3. NetFPGA-1G-CML Demo --- reference_router_nf1_cml

    环境 deepin 15.4 vivado 15.2 ise 14.6 前期准备 Github Wiki链接:https://github.com/NetFPGA/NetFPGA-public/wik ...

  4. scrapy csvfeed spider

    class CsvspiderSpider(CSVFeedSpider): name = 'csvspider' allowed_domains = ['iqianyue.com'] start_ur ...

  5. javabean 是什么?

    JavaBean规范 Bean的中文含义是“豆子”,顾名思义,JavaBean是指一段特殊的Java类, 就是有默然构造方法,只有get,set的方法的java类的对象. 专业点解释是: JavaBe ...

  6. Mysql数据库的触发程序

    /** **创建表 */ CREATE TABLE test1(a1 INT); CREATE TABLE test2(a2 INT); CREATE TABLE test3(a3 INT NOT N ...

  7. 在ArcGIS中导出现有mxd的style文件

     做好的地图包含许多地图符号,这是之前花了很多功夫做的,怎么把它导出来再用呢?     在ArcGIS中右键工具栏,customize,选择command选项卡,在搜索框中输入style ,选择too ...

  8. RAID6三块硬盘离线导致的数据丢失恢复过程

    小编我最近参与了一例非常成功的数据恢复的案例,在这里分享给大家.用户是一组6块750G磁盘的 RAID6,先后有两块磁盘离线,但维护人员在此情况下依然没有更换磁盘,所以在第三块硬盘离线后raid直接崩 ...

  9. GZip 压缩及解压缩

    /// <summary> /// GZipHelper /// </summary> public class GZipHelper { /// <summary> ...

  10. Linq 等式运算符:SequenceEqual

    检查元素的数量,每个元素的值及两个集合中元素的顺序是否相等,3个方面都相等则为true,否则为false IList<string> strList1 = new List<stri ...