松鼠的新家(lca)
洛谷—— P3258 [JLOI2014]松鼠的新家
题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入输出格式
输入格式:
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
输出格式:
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。
输入输出样例
5 1 4 5 3 2 1 2 2 4 2 3 4 5
1 2 1 2 1
说明
2<= n <=300000
思路:
对于这个题有些大佬肯定看一眼就能知道这个题是用的lca+插分做的吧。
(但像我这种蒟蒻是肯定不能一眼就看出来的!)
那有些人就要问啦,插分是个什么鬼?!
好,那我们先来说说插分吧!
随便写一个序列 3 6 2 7 5
它的查分序列是用后一个数减去前一个数,第一个数什么都不减就是它本身。
差分序列 3 3 -4 5 -2
差分序列有一个性质,就是你从头往后累加,加到第几个位置,现在累加的数就是原序列这个位置的数。
例如:差分序列加到第三个位置 3+3+(-4)=2;正好是原序列第三个位置的数。
应用一下吧。。。。我们要对一个区间的子区间进行操作.
例如[1,10];我们要将[4,6]这个区间的所有数加+1,求[4,6]的区间和。当然可以for循环挨个加1,求和;
那么差分是怎样求呢。我们只需更改两个位置,假如我们进行修改的区间是[l,r]。将a[l]+1,a[r+1]-1;即可完成区间的更改。
上面的例子 [4,6] .a[4]+1,a[6+1]-1;这样从头开始累加,由于我们在a[4]+1,我们从头累加到a[4-6]都会加+1;当我们累加到[4,6]
这个区间以外,由于a[6+1]已经-1,所以之后的累加都-1,都是它原来数的大小。为什么累加就是利用的差分序列的性质
来,我们来看看树上差分的结论:
1、将每条路径(s,t)上的每个点权值增加1,求各点权值。
将s、t点的权值加+1,lca(s,t)的权值-1,s和t的lca的爸爸-1。从叶子结点开始向上累加权值。
恍然大悟WAW。这道题真是赤裸裸的一道裸题啊。至于为什么那个点+那个点-,结合差分序列的性质自己顿悟。
2、找出被所有路径都覆盖的边
s,t的权值+1,s和t的lca的权值-2,从叶结点向上累加。
最终权值为路径数的点到其父亲的边为所求边。
所以我们把这个题访问的路径看成一个区间,区间的结点的权值都+1,就用差分做好了。
但是有一个坑,这一条路径的起点是这一条路径的终点,所以不能重复给糖,最后2--n减去1就可以。
好吧,废话少说,我们来直接看这道题的代码吧!
代码:
#include<vector> #include<stdio.h> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 300000+15 using namespace std; vector<int>vec[N]; int fa[N],deep[N],n,m,top[N],ans,size[N],x,y,f[N],a[N],z; int read(){ ,f=; char ch=getchar(); ') { ; ch=getchar(); } ') { x=x*+ch-'; ch=getchar(); } return x*f; } int lca(int x,int y) { while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); x=fa[top[x]]; } if(deep[x]>deep[y]) swap(x,y); return x; } void dfs(int x) { size[x]=; deep[x]=deep[fa[x]]+; ;i<vec[x].size();i++) if(vec[x][i]!=fa[x]) { fa[vec[x][i]]=x; dfs(vec[x][i]); size[x]+=size[vec[x][i]]; } } void dfs1(int x) { ; if(!top[x]) top[x]=x; ;i<vec[x].size();i++) if(vec[x][i]!=fa[x]&&size[vec[x][i]]>size[t]) t=vec[x][i]; if(t) top[t]=top[x],dfs1(t); ;i<vec[x].size();i++) if(vec[x][i]!=fa[x]&&t!=vec[x][i]) dfs1(vec[x][i]); } void dfs2(int x) { ;i<vec[x].size();i++) if(fa[x]!=vec[x][i]) dfs2(vec[x][i]),f[x]+=f[vec[x][i]]; } int main() { n=read(); ;i<=n;i++) a[i]=read(); ;i<n;i++) { x=read(),y=read(); vec[x].push_back(y); vec[y].push_back(x); } deep[]=; dfs(); dfs1(); ;i<=n;i++) { x=a[i-]; y=a[i];z=lca(x,y); f[x]++;f[fa[y]]++; f[z]--;f[fa[z]]--; } dfs2(); ;i<=n;i++) printf("%d\n",f[i]); ; }
松鼠的新家(lca)的更多相关文章
- [JLOI2014] 松鼠的新家 (lca/树上差分)
[JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在 ...
- 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀请小熊维尼前来 ...
- P3258[JLOI2014]松鼠的新家(LCA 树上差分)
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1231 Solved: 620[Submit][Stat ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家
[题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...
- [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)
题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- BZOJ 3631 【JLOI2014】 松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
随机推荐
- centos安装并配置MySQL
一.卸载掉原有mysql [root@xiaoluo ~]# rpm -qa | grep mysql // 这个命令就会查看该操作系统上是否已经安装了mysql数据库 [root@xiaoluo ~ ...
- Python基础——概述
新建Python代码 Jupyter Notebook是在浏览器中运行的. 地址栏输入http://localhost:8888后直接进入工作文件夹,显示文件夹中的内容. 右上角选择New——Pyth ...
- Python9-进程-day36
import osfrom multiprocessing import Processimport timedef func(args,args2): print(args,args2) time. ...
- socketserver的使用
socketserver底层也是使用线程实现的并发,直接上代码 # server import socketserver ''' socketserver使用模式: 1 功能类 class Myser ...
- POJ:1094-Sorting It All Out(拓扑排序经典题型)
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Description An ascending sorted sequence ...
- 新线程 handler
class CalculateThread extends Thread { private Handler handler; @Override public void run() { super. ...
- dubbo doc入门文档
dubbo document http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-protocol.html
- kruskal - 倍增 - 并查集 - Luogu 1967 货车运输
P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过 ...
- 对python的想法
作为计算机专业的学生,在编程语言之余,我认为掌握一门脚本语言是很必要的.尤其是现在在数据分析,AI,机器学习等各个方面都大放异彩的python.相比于之前接触过的Java,C,C++乃至于php等语言 ...
- 聊聊、Spring 第二篇
之前写了一篇<Spring环境搭建一>,感觉写的很烂,也许是时间有限,写的很急.今天我想再写写 Spring 的环境搭建,因为 Spring 的模块是可以单独拿出来用的,所以有很多的模块不 ...