【题目描述:】

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

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

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

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

【输入格式:】

第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an

接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

【输出格式:】

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

输入样例#: 

输出样例#: 

输入输出样例

【算法分析:】

根据小熊维尼走的路径记录每个点走过的次数,就是需要放的糖果数目

从点i走到点j, 可以看做:从i走到lca(i, j)再走到j是最短的路径。

而如何把i -> lca, j -> lca的点全部自增1呢?

可以用树上差分来维护,设定一个一维数组cha

对于从i到j的一条路径,

cha[i]++; cha[j]++;
cha[lca(i, j)]--;
cha[f[lca(i, j)][]]--;//点i, j最近公共祖先的父节点

然后从根节点开始dfs这棵树,对cha数组做一遍前缀和

最后对所有既是起点也是重点的点的经过次数-1.

【代码:】

 //P3258 [JLOI2014]松鼠的新家
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; const int MAXN = + ;
const int K = + ; int n, a[MAXN], ans[MAXN];
int cha[MAXN];
int deep[MAXN], f[MAXN][K];
int edge_num, head[MAXN];
struct Edge {
int to, next;
}h[MAXN << ]; inline int read() {
int x = , f = ; char ch = getchar();
while(ch < '' || ch > '') {
if(ch == '-') f = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
x = (x << ) + (x << ) + ch - , ch = getchar();
return x * f;
} inline void Add(int from, int to) {
h[++edge_num].to = to;
h[edge_num].next = head[from];
head[from] = edge_num;
} void build(int u) {
for(int i = head[u]; i != -; i = h[i].next) {
if(!deep[h[i].to]) {
deep[h[i].to] = deep[u] + ;
f[h[i].to][] = u;
build(h[i].to);
}
}
} inline void fill() {
for(int j = ; j < K; ++j)
for(int i = ; i <= n; ++i)
f[i][j] = f[f[i][j - ]][j - ];
} int lca(int a, int b) {
if(deep[a] > deep[b])
swap(a, b);
for(int i = K - ; i >= ; --i)
if(deep[f[b][i]] >= deep[a]) b = f[b][i];
if(a == b) return a;
for(int i = K - ; i >= ; --i) {
if(f[b][i] != f[a][i]) {
a = f[a][i], b = f[b][i];
}
}
return f[b][];
} void dfs(int u) {
for(int i = head[u]; i != -; i = h[i].next) {
if(h[i].to == f[u][]) continue;
dfs(h[i].to);
cha[u] += cha[h[i].to];
}
} int main() {
memset(head, -, sizeof(head));
n = read();
for(int i = ; i <= n; ++i) a[i] = read();
for(int i = ; i < n; ++i) {
int x = read(), y = read();
Add(x, y);
Add(y, x);
}
deep[a[n]] = ;
build(a[n]);
fill();
for(int i = ; i <= n; ++i) {
int com = lca(a[i], a[i - ]);
++cha[a[i]], ++cha[a[i - ]];
--cha[com], --cha[f[com][]];
}
dfs(a[n]);
for(int i = ; i <= n; ++i)
--cha[a[i]];
for(int i = ; i <= n; ++i)
printf("%d\n", cha[i]);
}

【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家的更多相关文章

  1. P3258[JLOI2014]松鼠的新家(LCA 树上差分)

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

  2. 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...

  3. 洛谷 P3258 [JLOI2014]松鼠的新家 题解

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

  4. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

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

  5. 洛谷P3258 [JLOI2014]松鼠的新家

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

  6. P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...

  7. 洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)

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

  8. 洛谷——P3258 [JLOI2014]松鼠的新家

    https://www.luogu.org/problem/show?pid=3258 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到 ...

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

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

随机推荐

  1. SpringBoot集成Jersey

    SpringBoot集成Jersey 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> & ...

  2. 使用mac下Fiddler的替代工具Charles进行手机抓包

    对手机的抓包有两种方式,各有优劣且互补,一般第一种即可,对于不走代理的 App 选择第二种方式 第一种 Fiddler: 利用 Fiddler 抓包,适合大多数走代理的应用, 优点 (1) 无需 ro ...

  3. WebApiTestHelpPage

    这是个什么鬼,第一次见到的时候,我也不知道就花几天时间看了下它的代码 在网上搜索WebApiTestHelpPage会出来很多相关页面   但是它们都是介绍怎么用的,要么就是怎么添加注释   它是怎么 ...

  4. UML 类图详解

    转载来源:http://blog.csdn.net/shift_wwx/article/details/79205187 可以参考:http://www.uml.org.cn/oobject/2012 ...

  5. Java8简明学习之接口默认方法

    接口中有默认方法实现Java8允许我们使用default关键字,为接口声明添加非抽象的方法实现. public interface DefaultInterFace { int plus(int x, ...

  6. element-ui中使用font-awesome字体图标

    element-ui提供的字体图标是很少的,所以我们需要集成其它图标来使用,nodejs的集成官方有说明,这里说明一下非nodejs开发集成图标 首先下载fontawesome,需要更改里面图标前缀, ...

  7. UVA11624(KB1-J)

    Fire! Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of ...

  8. 容易忽略的小知识之 Date 函数参数

    Date 对象启用基本存储器并取得日期和时间. dateObj = new Date()dateObj = new Date(dateVal)dateObj = new Date(year, mont ...

  9. 转:xdebug在linux下的安装教程

    原文:xdebug在linux下的安装教程 [注意,本人是PHP7.1.7 Nginx ,第7步没有做,但是xdebug.so就已经在PHP的扩展文件夹里面了.目录是phpinfo的extension ...

  10. http常见状态码有哪些?

    ajax常见面试题 1:什么是ajax?ajax作用是什么? 异步的javascript和xml AJAX 是一种用于创建快速动态网页的技术. ajax用来与后台交互 2:原生js ajax请求有几个 ...