[填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分。其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过。
我们先来把树上差分能做到的看一下:
1.找所有路径公共覆盖的边
例题:[NOIP2015]运输计划 (然而我还没过就先不讲了)
反正就是中间有一步要求一条边被所有计划公共覆盖。
那么怎么求它呢?暴力(滚粗)。我们有一个非常好的方法就是树上差分(记录tmp为差分数组)
询问操作为从叶子节点的权值向上累加到root
在一条路径u→ v,如果tmp[u]++,那么我们往上推的时候相当于u到root所有路径都被访问一次。同理tmp[v]++也意味如此。但是,lca(u,v)到root的路径都没有被访问过,但这里都被标记过两次,所以我们还要做的操作就是tmp[lca(u,v)]-=2;这样的话累加完之后tmp[i]记录的就是i节点被多少条路径覆盖了。
2.将路径上的所有点权值+1,最后求点权
例题:[JLOI2014]松鼠的新家 (这个我做过了hhh)
题目大意就是给你一些路径,把这个路径经过的点权+1,最后求所有点权。
这个题今天卡了我了。同学大佬有拿树剖求的,而且还要差分。但是我对于树上差分有点蒙蔽,于是搜了搜。然而蒟蒻的我搜到了LCA解法,于是兴高采烈的打(chao)了(le)出来。这里的差分有一些不同。因为我们要找的是点的覆盖。所以我们对于u→ v,tmp[u]++,tmp[v]++,tmp[lca(u,v)]--,tmp[fa[lca(u,v)]]--;这个想必大家能看懂吧。
于是,我们就欢快的求出了所有点被修改后的权值。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
#define N 301000
struct haha{
int next,to;
}edge[N*2];
int head[N],cnt=1,p[N][20];
void add(int u,int v){
edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;
}
int a[N],n,fa[N],dep[N];
void dfs(int x){
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(fa[x]!=to){
fa[to]=x;dep[to]=dep[x]+1;
dfs(to);
}
}
}
void init(){
int j;
for(j=0;(1<<j)<=n;j++){
pos(i,1,n) p[i][j]=-1;
}
pos(i,1,n){
p[i][0]=fa[i];
}
for(j=1;(1<<j)<=n;j++){
pos(i,1,n){
if(p[i][j-1]!=-1){
p[i][j]=p[p[i][j-1]][j-1];
}
}
}
}
int lca(int a,int b){
int i;
if(dep[a]<dep[b]) swap(a,b);
for(i=0;(1<<i)<=dep[a];i++);
i--;
for(int j=i;j>=0;j--)
if(dep[a]-(1<<j)>=dep[b])
a=p[a][j];
if(a==b) return a;
for(int j=i;j>=0;j--){
if(p[a][j]!=-1&&p[a][j]!=p[b][j]){
a=p[a][j];b=p[b][j];
}
}
return fa[a];
}
int tmp[N];
void work(int x){
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(fa[x]!=to){
work(to);
tmp[x]+=tmp[to];
}
}
}
int main(){
scanf("%d",&n);
pos(i,1,n)
scanf("%d",&a[i]);
pos(i,1,n-1){
int x,y;scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(a[1]);
init();
pos(i,1,n-1){
int u=a[i],v=a[i+1];
tmp[u]++;tmp[v]++;
tmp[lca(u,v)]--;tmp[fa[lca(u,v)]]--;
}
work(a[1]);
pos(i,2,n) tmp[a[i]]--;
pos(i,1,n) printf("%d\n",tmp[i]);
return 0;
}
[填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)的更多相关文章
- [JLOI2014] 松鼠的新家 (lca/树上差分)
[JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在 ...
- P3258[JLOI2014]松鼠的新家(LCA 树上差分)
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀请小熊维尼前来 ...
- 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家
[题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...
- luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)
P3258 [JLOI2014]松鼠的新家 题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...
- [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2350 Solved: 1212[Submit][Sta ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...
- [Luogu 3258] JLOI2014 松鼠的新家
[Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...
随机推荐
- [leetcode-563-Binary Tree Tilt]
Given a binary tree, return the tilt of the whole tree.The tilt of a tree node is defined as the abs ...
- eclipse更改maven的本地路径和外部仓库地址
背景 当前使用eclipse自带的maven碰到两个蛋疼的问题: maven在国内使用如果不进行FQ则会痛苦不堪如便秘. maven下载大量jar包导致某盘不够用,需要换大的分区. 因此为了解决这个问 ...
- Swift实现JSON转Model - HandyJSON使用讲解
背景: 很多时候,我们从服务端请求下的数据都是Json格式,我们需要拿这些数据显示到我们的UI界面. 因此,我们的做法基本都会先将json转为方便使用的数据模型,或者也可以直接转字典解决. 在OC中, ...
- Win环境下Oracle小数据量数据库的物理备份
Win环境下Oracle小数据量数据库的物理备份 环境:Windows + Oracle 单实例 数据量:小于20G 重点:需要规划好备份的路径,建议备份文件和数据库文件分别存在不同的存储上. 1.开 ...
- orcle 索引的使用
2.4.3.1. 索引的概念 数据库中的索引与书籍中的索引类似,在一本书中,利用索引可以快速查找所需信息, 无须阅读整本书.在数据库中,索引使数据库程序无须对整个表进行扫描, 就可以在其中找到所需数据 ...
- Spring Security @PreAuthorize 拦截无效
1. 在使用spring security的时候使用注解,@PreAuthorize("hasAnyRole('ROLE_Admin')") 放在对方法的访问权限进行控制失效,其中 ...
- Kintinuous 相关论文 Volume Fusion 详解
近几个月研读了不少RGBD-SLAM的相关论文,Whelan的Volume Fusion系列文章的效果确实不错,而且开源代码Kintinuous结构清晰,易于编译和运行,故把一些学习时自己的理解和经验 ...
- classloader加载的双亲委托模式
要深入了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用 的.我们知道,java程序可以动态加载类定义,而这个动 ...
- PHP----SAPI
SAPI:Server Application Programming Interface 服务器端应用编程端口.它就是PHP与其它应用交互的接口,PHP脚本要执行有很多种方式,通过Web服务器,或者 ...
- docker~使用阿里加速器安centos
回到目录 上一篇说了hub.docker.com里拉个镜像太,而阿里云为我们做了不少本国镜像,这样下载的速度就很惊人了,下面看一下在centos7下配置阿里云加速器的方法 打开服务配置文件 vi /e ...