bzoj3631[JLOI2014 松鼠的新家 倍增lca+差分
裸的树上差分+倍增lca
每次从起点到终点左闭右开,这就有一个小技巧,要找到右端点向左端点走的第一步,然后差分就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define N 300005
using namespace std;
int fa[N][20],dep[N],f[N],g[N],n,l[N];
int e=1,head[N];
struct edge{
int u,v,next;
}ed[2*N];
void add(int u,int v){
ed[e].u=u;ed[e].v=v;
ed[e].next=head[u];
head[u]=e++;
}
void dfs(int x){
for(int i=1;(1<<i)<=dep[x];i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa[x][0])continue;
fa[v][0]=x;dep[v]=dep[x]+1;
dfs(v);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=19;i>=0;i--)
if(dep[fa[x][i]]>=dep[y])
x=fa[x][i];
if(x==y)return x;
for(int i=19;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int find(int x,int y){
int d=dep[x]-y;
for(int i=19;~i;i--)
if(dep[fa[x][i]]>=d)
x=fa[x][i];
return x;
}
void update(int x,int y){
f[x]++;f[y]++;
int z=lca(x,y);
f[z]--;f[fa[z][0]]--;
}
void work(int x,int y){
if(dep[x]<=dep[y])update(x,fa[y][0]);
else{
int d=dep[x]-dep[y];
int z=find(x,d-1);
if(fa[z][0]==y)update(x,z);
else update(x,fa[y][0]);
}
}
void dfs1(int x){
g[x]=f[x];
for(int i=head[x];i;i=ed[i].next){
if(ed[i].v==fa[x][0])continue;
dfs1(ed[i].v);
g[x]+=g[ed[i].v];
}
}
int main(){
scanf("%d",&n); int u,v;
for(int i=1;i<=n;i++)scanf("%d",&l[i]);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dep[1]=1; dfs(1);
for(int i=1;i<n;i++)
work(l[i],l[i+1]);
dfs1(1);
for(int j=1;j<=n;j++)
printf("%d\n",g[j]);
return 0;
}
bzoj3631[JLOI2014 松鼠的新家 倍增lca+差分的更多相关文章
- bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)
题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...
- [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)
题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】
题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松鼠想 ...
- bzoj3631: [JLOI2014]松鼠的新家(树上差分)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 题目大意:给定含有n个顶点的树,给定走遍整棵树顺序的序列a[1],a[2],a[3 ...
- luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)
P3258 [JLOI2014]松鼠的新家 题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2350 Solved: 1212[Submit][Sta ...
- 洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- 洛谷P3258 [JLOI2014]松鼠的新家【LCA+树上差分】
简要题意 树上n个节点,给定路径,求每个点经过次数 题意分析 对于每两个点,有两种情况,第一种,他们的lca为本身,第二种,他们有公共祖先,又要求他们的点经过次数,暴力是不可能的,复杂度不对,所以可以 ...
随机推荐
- Salesforce的数据权限机制
本文主要介绍了 Salesforce 对于系统中数据的访问控制是如何设计的,然后也了解了下 Alfresco 和 Oracle VPD 的数据权限机制.希望对一些业务系统的数据权限的访问控制设计能有所 ...
- Event 对象
哪个鼠标按钮被点击? <html> <head> <script type="text/javascript"> function whichB ...
- for 循环为何可恨?
Java的闭包(Closure)特征最近成为了一个热门话题. 一些精英正在起草一份议案,要在Java将来的版本中加入闭包特征. 然而,提议中的闭包语法以及语言上的这种扩充受到了众多Java程序员的猛烈 ...
- Java语言概论
第1章 ■ Java的发展简史及特点 ■ J2SDK的下载与安装 ■ Java应用程序的编写 ■ Eclipse的下载及使用 ■ 正确安装使用J2SDK ■ 使用记 ...
- struts2.1.8+hibernate2.5.6+spring3.0(ssh2三大框架)常见异常原因和解决方案
---------------------------------------------------------------------------------------------------- ...
- C4 垃圾回收
使用C4垃圾回收器可以有效提升对低延迟有要求的企业级Java应用程序的伸缩性. 到目前为止,stop-the-world式的垃圾回收视为影响Java应用程序伸缩性的一大障碍,而伸缩性又是现代企业级Ja ...
- 交换机设置IP
二成交换机所有端口在默认情况下都是属于vlan1的 代表整个交换机 你只需要设置vlan1的ip地址就行了 进入交换机配置界面后 命令如下:enableconfigure terminalinterf ...
- Java内存模型与指令重排
Java内存模型与指令重排 本文暂不讲JMM(Java Memory Model)中的主存, 工作内存以及数据如何在其中流转等等, 这些本身还牵扯到硬件内存架构, 直接上手容易绕晕, 先从以下几个点探 ...
- mysql-索引、关系、范式
索引 几乎所有的索引都是建立在字段之上 索引:系统根据某种算法,将已有的数据(未来可能新增的数据也算),单独建立一个文件,这个文件能够快速的匹配数据,并且能够快速的找到对应的表中的记录 索引意义 能够 ...
- Android 资源文件命名与使用
[推荐]资源文件需带模块前缀 [推荐]layout 文件的命名方式 Activity 的 layout 以 module_activity 开头 Fragment 的 layout 以 module_ ...