题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(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 + 树上差分

对于访问序号我们将其变成边的形式。

对于所有的的边,

我们会发现第一条和最后一条是特殊的。

  1. 第一条是两个端点都是包含的, 即在两个端点上都放糖果:[u,v]

  2. 最后一条是两个端点都不包含, 即在两个端点上不放糖果:(u,v)

  3. 其余的路径都是一样的,前一个包含,后一个不包含:[u,v)

f数组是倍增lca数组,u和v分别是一边的端点。

  1. 先看第一条边,直接进行树上差分,无特殊处理。

  2. 最后一条边,我们要进行讨论,一共有3种情况:

    1. u != LCA && v != LCA,那么我们要差分的边就是f[u][0]-f[v][0].
    2. u == LCA && v != LCA,那么我们要差分的边就是son[u]-f[v][0].
    3. u != LCA && v == LCA,那么我们要差分的边就是f[u][0]-son[v].
  3. 其余的边,也是讨论3种情况:

    1. u != LCA && v != LCA,那么我们要差分的边就是f[u][0]-v.
    2. u == LCA && v != LCA,那么我们要差分的边就是son[u]-v.
    3. u != LCA && v == LCA,那么我们要差分的边就是f[u][0]-v

做完这些,就是树上差分的板子了,这里就不赘述了。

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <stack>
#include <algorithm>
#define re register
#define gc getchar
inline int read() {
int s = 0, f = 1; char ch = gc();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = gc();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = gc();
return s * f;
}
inline int min(int a, int b) {return a < b ? a : b;}
inline int max(int a, int b) {return a > b ? a : b;}
const int INF = 0x7fffffff;
const int Max = 600012;
const int mod = 19260817;
const int N = 1000007;
struct Candy {
int net, to;
}t[Max];
int n, head[Max], cnt, f[Max][21];
int x[Max], y[Max], k[Max], deep[Max];
inline void insert(int u, int v) {
t[++cnt].to = v;
t[cnt].net = head[u];
head[u] = cnt;
}
void dfs(int x, int Fa) {
f[x][0] = Fa; deep[x] = deep[Fa] + 1;
for(int i = 1; (1 << i) <= deep[x]; i++)
f[x][i] = f[f[x][i-1]][i-1];
int v;
for(re int i = head[x]; i; i = t[i].net) {
v = t[i].to;
if(v == Fa) continue;
dfs(v,x);
}
}
int lca(int x, int y) {
if(deep[x] < deep[y]) std :: swap(x, y);
for(re int i = 21; i >= 0; -- i)
if(deep[x] - (1 << i) >= deep[y])
x = f[x][i];
if(x == y) return x;
for(re int i = 20; i >= 0; -- i)
if(f[x][i] == f[y][i]) continue;
else x = f[x][i], y = f[y][i];
return f[x][0];
}
void SUM(int x, int Fa) {
int v;
for(re int i = head[x]; i; i = t[i].net) {
v = t[i].to; if(v == Fa) continue;
SUM(v, x); k[x] += k[v];
}
}
int find_son(int x, int LCA) {
int depth = deep[LCA] + 1;
for(re int i = 21; i >= 0; -- i)
if(deep[x] - (1 << i) >= depth)
x = f[x][i];
return x;
}
int main() {
n = read(); int u, v; x[1] = read();
for(re int i = 1; i < n; ++ i) y[i] = read(), x[i+1] = y[i];
for(re int i = 1; i < n; ++ i)
u = read(), v = read(), insert(u,v), insert(v,u);
dfs(1,0);
int LCA = lca(x[n-1], y[n-1]); bool fg = 1;
if(x[n-1] != LCA && y[n-1] != LCA)
u = f[x[n-1]][0], v = f[y[n-1]][0];
else if(x[n-1] == LCA && y[n-1] != LCA) {
u = find_son(y[n-1], LCA), v = f[y[n-1]][0];
if(f[y[n-1]][0] == x[n-1]) fg = 0;
}
else if(x[n-1] != LCA && y[n-1] == LCA) {
u = f[x[n-1]][0], v = find_son(x[n-1], LCA);
if(f[x[n-1]][0] == y[n-1]) fg = 0;
}
LCA = lca(u, v);
if(fg) k[u] ++, k[v] ++, k[LCA] --, k[f[LCA][0]] --;
u = x[1]; v = y[1]; LCA = lca(u, v);
k[u] ++, k[v] ++, k[LCA] --, k[f[LCA][0]] --;
for(re int i = 2; i < n - 1; ++ i) {
LCA = lca(x[i], y[i]);
if(x[i] != LCA && y[i] != LCA)
u = f[x[i]][0], v = y[i];
else if(x[i] == LCA && y[i] != LCA)
u = find_son(y[i], LCA), v = y[i];
else if(x[i] != LCA && y[i] == LCA)
u = f[x[i]][0], v = y[i];
LCA = lca(u,v);
k[u] ++, k[v] ++, k[LCA] --, k[f[LCA][0]] --;
}
SUM(1,0);
for(re int i = 1; i <= n; ++ i) printf("%d\n",k[i]);
return 0;
}

P3258 [JLOI2014]松鼠的新家题解的更多相关文章

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

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

  2. P3258 [JLOI2014]松鼠的新家

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

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

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

  4. 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家

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

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

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

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

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

  7. luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)

    P3258 [JLOI2014]松鼠的新家  题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...

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

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

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

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

随机推荐

  1. 服务器个人环境下pytorch0.4.1编译warp-ctc遇到的问题及解决方法

    一.关于warp-ctc CTC可以生成一个损失函数,用于在序列数据上进行监督式学习,不需要对齐输入数据及标签,经常连接在一个RNN网络的末端,训练端到端的语音或文本识别系统.CTC论文 CTC网络的 ...

  2. 024 如何让html引用公共的头部和尾部(多个html文件公用一个header.html和footer.html)

    前端静态html页面,封装公共的头文件(header:顶部页眉,顶部导航栏等部分)和尾部文件(footer:CopyRight.友情链接等部分) 当前方法:通过load()函数,引入公共头部和尾部文件 ...

  3. [转帖]微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务

    微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务 http://skaka.me/blog/2016/04/21/springcloud1/ APR 21ST,  ...

  4. why’s kafka so fast

    As we all know that Kafka is very fast, much faster than most of its competitors. So what’s the reas ...

  5. Unity3d—GUI能量条

    1.打开Unity编辑器. 2.在脚本文件夹中添加C#脚本,我的是添加了skill_01这个脚本.(要自己设置文件夹,方便管理,不然文件添乱不方便管理) 3.注意,脚本的名字一旦确定就不要去改动,因为 ...

  6. Window 远程桌面漏洞风险,各个厂家的扫描修复方案(CVE-2019-0708)

    自微软公司于2019年5月14日发布远程桌面服务远程代码执行漏洞(CVE-2019-0708)安全公告后,整个业界都一直在密切关注,这个漏洞编号必将在当今网络中掀起腥风血雨.各大厂商也纷纷推出自己的修 ...

  7. excel中统计COUNTIFS的值为0

    excel中统计COUNTIFS的值为0 个人认为是由于导出的文件里面的字符个数问题 使用 =COUNTIFS(H1:H175,"微信支付") 这个的结果居然是0,找了很多办法 于 ...

  8. WPF 精修篇 动画组TransformGroup

    原文:WPF 精修篇 动画组TransformGroup 动画分组 TransformGroup 一个元素可能要有缩放 ScaleTransform和移动 TranslateTransform等多个效 ...

  9. 获取post传输参数

    1.获取post参数可以用 传输参数为 a=aa&b=bb这种 public static SortedDictionary<string, string> GetRequestP ...

  10. CentOS 7.0 使用yum 安装 Mariadb

    第一步: 使用命令查看是否已经安装: mysql -u root -p 返回 Enter password:  时表示已经安装成功的,需要卸载安装. 第二步: 使用yum直接安装mariadb,注意带 ...