洛谷P3258 [JLOI2014]松鼠的新家【LCA+树上差分】
简要题意
树上n个节点,给定路径,求每个点经过次数
题意分析
对于每两个点,有两种情况,第一种,他们的lca为本身,第二种,他们有公共祖先,又要求他们的点经过次数,暴力是不可能的,复杂度不对,所以可以想到树上差分再求前缀和,在差分的过程中自然也要求lca了。
还有要注意的就是对于开始的起点和结束的终点是要特判经过的,其他的起点不计入次数。
树上差分
树上差分主要用于求解一些树上的路径问题
它通过利用树的一些性质,用一个差分数组来实现对一条路径的操作,这涉及到路径的 起,终点 与lca。
一般情况下:一个点的真实权值为其所在子树内所有点的差分数组的值的和
树上差分一般不适用于询问和操作嵌套的题目,这时一般用树链剖分解决
LCA
倍增Tarjan树剖,自行百度
关于代码:
#include<bits/stdc++.h>
#define re register
#define ll long long
#define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
using namespace std;
inline int read()
{
int k=1,sum=0;
char c=getchar();
for(;c<'0' || c>'9';c=getchar()) if(c=='-') k=-1;
for(;c>='0' && c<='9';c=getchar()) sum=sum*10+c-'0';
return sum*k;
}
const int N=3e5+10;
struct Edge
{
int to,nxt;
}edge[N*2];
int head[N],cnt;
inline void Add(int x,int y)
{
edge[++cnt].to=y;edge[cnt].nxt=head[x];head[x]=cnt;
}
int n;
int a[N];
queue<int> Q;
int dep[N];
int t;
int f[N][26];
int cf[N];
inline void bfs()
{
Q.push(1);
dep[1]=1;
while(!Q.empty())
{
int x=Q.front();Q.pop();
for(re int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if(dep[y]) continue;
dep[y]=dep[x]+1;
f[y][0]=x;
for(re int j=1;j<=t;++j) f[y][j]=f[f[y][j-1]][j-1];
Q.push(y);
}
}
}
inline int LCA(int x,int y)
{
if(dep[x]>dep[y]) swap(x,y);
for(re int i=t;i>=0;--i) if(dep[f[y][i]]>=dep[x]) y=f[y][i];
if(x==y) return x;
for(re int i=t;i>=0;--i) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
bool vis[N];
inline void dfs(int x)
{
vis[x]=1;
for(re int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if(vis[y]) continue;
dfs(y);
cf[x]+=cf[y];
}
}
int main()
{
n=read();t=(log(n)/log(2))+1;
for(re int i=1;i<=n;++i) a[i]=read();
for(re int i=1;i<n;++i)
{
int x=read(),y=read();
Add(x,y);Add(y,x);
}
bfs();
for(re int i=1;i<n;++i)
{
int start=a[i],to=a[i+1],lca=LCA(start,to);
if(i==1)
{
if(lca==start) {++cf[to];--cf[f[start][0]];continue;}
if(lca==to) {++cf[start];--cf[f[to][0]];continue;}
++cf[start];++cf[to];--cf[lca];--cf[f[lca][0]];continue;
}
if(i==n-1)
{
if(lca==start) {++cf[f[to][0]];--cf[start];continue;}
if(lca==to) {++cf[f[start][0]];--cf[to];continue;}
++cf[f[start][0]];++cf[f[to][0]];--cf[lca];--cf[f[lca][0]];continue;
}
if(lca==start) {++cf[to];--cf[start];continue;}
if(lca==to) {++cf[f[start][0]];--cf[f[to][0]];continue;}
++cf[f[start][0]];++cf[to];--cf[lca];--cf[f[lca][0]];
}
dfs(1);
for(re int i=1;i<=n;++i) cout<<cf[i]<<endl;
return 0;
}
洛谷P3258 [JLOI2014]松鼠的新家【LCA+树上差分】的更多相关文章
- 洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- P3258[JLOI2014]松鼠的新家(LCA 树上差分)
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 题解
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- [JLOI2014] 松鼠的新家 (lca/树上差分)
[JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)
题目描述松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前来 ...
- 洛谷——P3258 [JLOI2014]松鼠的新家
https://www.luogu.org/problem/show?pid=3258 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家
树剖,裸题,鉴定完毕. 我是题面 读完题,恩,树剖,裸题,没劲. 处理很简单,既然每到一个房间吃一块糖,那么就在每条路径上的每个房间放一颗糖,但是每条路径的终点也就是下一条路径的起点,在这里只能加一次 ...
随机推荐
- Winform中设置ZedGraph曲线图的水平与竖直参考线
场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- airflow使用本地时区
在airflow中使用的时间是utc时间,而更多时候我们希望的是使用本地时间,于是在定义airflow定时任务的时候,涉及到了时间的转换. 1.python中本地时间和utc时间的转换 查看国内可 ...
- 从零开始入门 K8s| 阿里技术专家详解 K8s 核心概念
作者| 阿里巴巴资深技术专家.CNCF 9个 TCO 之一 李响 一.什么是 Kubernetes Kubernetes,从官方网站上可以看到,它是一个工业级的容器编排平台.Kubernetes 这个 ...
- Spring——面向切面编程(AOP)详解
声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...
- 为什么需要OLAP DSL?
OLAP(On-Line Analytical Processing,联机分析处理)是大数据场景中,数据价值探索与挖掘的重要环节.这个领域内,开源社区呈现百花齐放的现象,Elasticsearch.D ...
- List之ConcurrentModificationException异常
一.前言 Java开发工作中,集合类ArrayList应该是使用非常频繁了.在使用过程中,可能会遇到迭代删除的需求场景,此时如果代码书写不当,就会抛出 java.util.ConcurrentModi ...
- 关于canvas合成分享图
最近在uni-app项目中遇到一个合成分享图的需求,其实最开始是用原生写法来做的,后台发现在PC端测试是可以的,但在APP模拟器中会出现问题,可能是因为两者的js环境不同吧,uni-app官网也说了这 ...
- 【ADO.NET-中级】百万级数据的批量插入的两种方法测试
在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量 ...
- JS 生成唯一值UUID
md5加密new Date()生成的值可能不是唯一的,另一种生成唯一值的方式: getUID: function() { // 获取唯一值 return 'xxxxxxxx-xxxx-4xxx-yxx ...
- .NET进阶篇-丑话先说,Flag先立--致青春
作为开发者,工作了半年,也总觉得技术栈和刚毕业区别不大,用的技术还都是N年前的,每每看到新东西,也只心里哇塞惊叹一下,然后就回归于忙碌.怪自己的技术池太浅,热门的令人称奇的技术也都是在其他巨人的肩膀上 ...