P3258 [JLOI2014]松鼠的新家题解
题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(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 + 树上差分
对于访问序号我们将其变成边的形式。
对于所有的的边,
我们会发现第一条和最后一条是特殊的。
第一条是两个端点都是包含的, 即在两个端点上都放糖果:[u,v]
最后一条是两个端点都不包含, 即在两个端点上不放糖果:(u,v)
其余的路径都是一样的,前一个包含,后一个不包含:[u,v)
f数组是倍增lca数组,u和v分别是一边的端点。
先看第一条边,直接进行树上差分,无特殊处理。
最后一条边,我们要进行讨论,一共有3种情况:
u != LCA && v != LCA,那么我们要差分的边就是f[u][0]-f[v][0].u == LCA && v != LCA,那么我们要差分的边就是son[u]-f[v][0].u != LCA && v == LCA,那么我们要差分的边就是f[u][0]-son[v].
其余的边,也是讨论3种情况:
u != LCA && v != LCA,那么我们要差分的边就是f[u][0]-v.u == LCA && v != LCA,那么我们要差分的边就是son[u]-v.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]松鼠的新家题解的更多相关文章
- 洛谷 P3258 [JLOI2014]松鼠的新家 题解
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家
[题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...
- 洛谷P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- P3258[JLOI2014]松鼠的新家(LCA 树上差分)
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)
P3258 [JLOI2014]松鼠的新家 题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)
题目描述松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前来 ...
随机推荐
- 【记录】【idea】【mysql】Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.解决问题
idea连接mysql报错Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property ...
- VHR配置数据库开发环境
一,vhr项目宏观分析 目的:实现机关和事业单位的人事管理信息系统. 软件使用的对象:面向机关和事业单位内人事信息管理人员和在职开发人员. [架构选型] vhr面向的群体范围并不大,并非属于互联网应用 ...
- 【09】Jenkins:Pipeline 补充
写在前面的话 我们在使用普通的构建任务的时候使用了 Sonar 做代码质量管理,也使用了 Publish Over SSH 插件中更新上线,但是我们在 Pipeline 怎么使用他们呢. 如果你没有查 ...
- Python 3 的 int 类型详解(为什么 int 不存在溢出问题?)
在以前的Python2中,整型分为int和long,也就是整型和长整型, 长整型不存在溢出问题, 即可以存放任意大小的数值,理论支持无限大数字. 因此在Python3 中,统一使用长整型,用int表示 ...
- mysqlbinlog恢复误删数据
概述 代码bug,在处理上传出现异常时执行了DELETE FROM t_resource WHERE resource_id = ? OR parent_id = ?因为OR条件导致用户的上传的所有数 ...
- .NET MVC 支付宝支付(即时到账)
已经好久没有搞过.NET了,朋友有一个网站 ,需要接入支付宝功能,重新对接了一下. 1.开发前,需要一个企业支付宝账号登录,获取 PID和 配置密钥 官方文档:https://docs.open.al ...
- RabbitMQ系列(二)环境搭建
参考: https://www.cnblogs.com/ericli-ericli/p/5902270.html https://blog.csdn.net/weixin_30619101/artic ...
- nginx 反向代理时丢失端口的解决方案(转)
今天,配置nginx反向代理时遇到一个问题,当设置nginx监听80端口时转发请求没有问题.但一旦设置为监听其他端口,就一直跳转不正常:如,访问欢迎页面时应该是重定向到登录页面,在这个重定向的过程中端 ...
- maven 镜像仓库 setting.xml修改 & 手动导入的包如何加到maven里面
如果不知道maven安装路径IDEA中打File->Settings 再点Build->Maven右边看maven安装路径,打开这个路径,再打开conf/settings.xml文件 ...
- linq to js 用法
/** * 排序汇总 * */ var result = Enumerable.From(vm.productList).GroupBy("$.goods_id", null, f ...