洛谷 P3258 [JLOI2014]松鼠的新家 题解
P3258 [JLOI2014]松鼠的新家
题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入格式
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an
接下来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
【思路】
倍增/树链剖分 + 树上差分
很有意思很有意思的一道题目
会了树上差分几乎就是一个板子题
不,是两个板子题
倍增/树链剖分板子 + 树上差分板子
先dfs出这棵树每个点的深度和他跳2^n之后会跳到哪一个点
然后按照题目给出的到达房间的顺序
找 \(a_1\)和 \(a_2\)的LCA, \(a_2\) 和 \(a_3\) 的LCA……
然后运用树上差分
将 \(a_i\) 和 \(a_i+1\) 的差分数组都加上1,
然后将LCA和LCA夫妻的差分数组都减去1
最后一个递归递归出每个店的值
输出就好了
注意:
这里有n-1个点作为了起点也作为了终点
所以重复了1次
判断一下重复过的在输出的时候顺手减去1就好了
【完整代码】
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int Max = 300005;
struct node
{
int y;
int ne;
}s[Max << 1];
int a[Max];
int depth[Max];
int fa[Max][23];
int head[Max];
int sum = 0;
int c[Max];
int ans[Max];
void add(int x,int y)
{
s[++ sum].y = y;
s[sum].ne = head[x];
head[x] = sum;
s[++ sum].y = x;
s[sum].ne = head[y];
head[y] = sum;
}
void dfs(int f,int fath)
{
depth[f] = depth[fath] + 1;
fa[f][0] = fath;
for(register int i = 1;(1 << i) <= depth[f];++ i)
fa[f][i] = fa[fa[f][i - 1]][i - 1];
for(int i = head[f];i != 0;i = s[i].ne)
if(s[i].y != fath)
dfs(s[i].y,f);
}
int lca(int x,int y)
{
if(depth[x] < depth[y])swap(x,y);
for(register int i = 22;i >= 0;i --)
if(depth[fa[x][i]] >= depth[y])
x = fa[x][i];
if(x == y)return x;
for(register int i = 22;i >= 0;i --)
if(fa[x][i] != fa[y][i])
x = fa[x][i],y = fa[y][i];
return fa[x][0];
}
/*
void doit(int x)
{
ans[x] = c[x];
while(fa[x][0] != 0)
{
ans[fa[x][0]] += ans[x] + a[fa[x][0]];
x = fa[x][0];
}
}
void search(int x)
{
int js = 0;
for(register int i = head[x];i != 0;i = s[i].ne)
{
int qwq = s[i].y;
if(qwq != fa[x][0])
{
js ++;
ans[qwq] = ans[x] + c[qwq];
search(qwq);
}
}
if(js == 0)
doit(x);
}
*/
int search(int x)
{
ans[x] = c[x];
for(register int i = head[x];i != 0;i = s[i].ne)
{
int qwq = s[i].y;
if(qwq != fa[x][0])
ans[x] += search(qwq);
}
return ans[x];
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int n;
cin >> n;
int x,y;
for(register int i = 1;i <= n;++ i)
cin >> a[i];
for(register int i = 1;i < n;++ i)
cin >> x >> y,add(x,y);
dfs(1,0);
//fa[1][0] = 1;
for(register int i = 1;i < n;++ i)
{
int LCA = lca(a[i],a[i + 1]);
c[LCA] -= 1;c[fa[LCA][0]] -= 1;
c[a[i]] ++;c[a[i + 1]] ++;
}
/*
for(int i = 1;i <= n;++ i)
cout << c[i] << endl;
*/
int acioi = search(1);
for(register int i = 1;i <= n;++ i)
{
if(i == a[1])
cout << ans[i] << endl;
else
cout << ans[i] - 1<< endl;
}
return 0;
洛谷 P3258 [JLOI2014]松鼠的新家 题解的更多相关文章
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)
题目描述松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前来 ...
- 洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- 洛谷——P3258 [JLOI2014]松鼠的新家
https://www.luogu.org/problem/show?pid=3258 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家
树剖,裸题,鉴定完毕. 我是题面 读完题,恩,树剖,裸题,没劲. 处理很简单,既然每到一个房间吃一块糖,那么就在每条路径上的每个房间放一颗糖,但是每条路径的终点也就是下一条路径的起点,在这里只能加一次 ...
- 洛谷P3258 [JLOI2014]松鼠的新家【LCA+树上差分】
简要题意 树上n个节点,给定路径,求每个点经过次数 题意分析 对于每两个点,有两种情况,第一种,他们的lca为本身,第二种,他们有公共祖先,又要求他们的点经过次数,暴力是不可能的,复杂度不对,所以可以 ...
- P3258 [JLOI2014]松鼠的新家题解
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(n\)个房间,并且有\(n-1\)根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树& ...
随机推荐
- git 学习笔记 ---远程仓库
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的, ...
- charles4.0 request和response的显示设置
点击右上角的设置按钮 点击preferences 切换到viewers,取消勾选Combine request and response,点击保存即可
- Centos Consul集群及Acl配置
一,准备工作 准备四台centos服务器,三台用于consul server 高可用集群,一台用于consul client作服务注册及健康检查.架构如下图所示 二,在四台服务器上安装consul 1 ...
- js 简单的滑动1
js 简单的滑动教程(一) 作者:Lellansin 转载请标明出处,谢谢 首先我们要实现一个简单的滑动,三张图.点击左边向左滑动,点右向右滑,碰到临界值的时候就不能滑动. 这个简单滑动的原理是, ...
- ios开发之NSData
NSData用于保存字节数组. 初始化 - (instancetype)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length free ...
- php实现人员权限管理(用户界面)
上一篇介绍的是管理员页面,能完成对用户的角色修改和保存,这里来说一下用户界面,用户通过登录,显示出其对应功能界面. 1.登录页面(用的ajax,也可以用php表单提交方式) <!DOCTYPE ...
- mysql学习之基础篇07
视图:view 在查询的时候我们经常把查询到的结果当成一张临时表来看,其实view就可以看成一张虚拟表,是表通过某种运算得到的投影 那么如何创建视图?创建视图需要指定视图的列名和列类型吗? 答:不用, ...
- 使用jib上传docker镜像
Jib 无需Docker守护程序即可为Java应用程序构建优化的Docker和OCI映像-无需深入了解Docker最佳实践.它可以作为Maven和Gradle的插件以及Java库使用. 我使用的是Ma ...
- ACL权限
基本命令 getfacl 文件名 查看文件ACL权限 setfacl [选项] 文件名 设定文件ACL权限 -m 设定ACL权限 -b 删除ACL权限 -x:用户 删除单个用户的ACL权限 s ...
- 使用Cloudera Manager搭建Hive服务
使用Cloudera Manager搭建Hive服务 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装Hive环境 1>.进入CM服务安装向导 2>.选择需要 ...