luoguP3258 [JLOI2014]松鼠的新家
树上差分
树上差分分析
使点x到点y的路径上(链上),全加上一个值,可以选择使用树上差分(不用线段树乱搞....
首先,和普通的差分一样,要有一个tag。然而,对于一个结点,我们需要求出它全部儿子的tag之后,才能算它的tag,进而算出它的值。所以,我们需要每个节点开一个tag(不然在依次遍历儿子的时候,轻儿子的tag不就乱了嘛...会影响的嘛)(前一个括号纯属口胡,就是一个博主的sb错误)
具体操作:(cf意为差分数组)
cf[x] + 1
cf[y] + 1
cf[ lca(x,y) ] - 1 //lca(x,y)算了两遍
cf[ fa[ lca(x,y) ] ] - 1 //为了不对其它的链产生影响
裸栗题
https://www.luogu.org/problem/P3258
这题注意一下: 如果出现这样的情况:x~y, y~z, 即连续进行差分, 需要注意:cf[y]加了两次,而这题中,y是不用加两次的,所以把ans[y]--,即可 (这个操作引题而异吧,自己多想想)
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 300000+99;
const int MAXM = MAXN<<1;
int n;
struct node{
int size, deep, son, tp, fa, cf, tag;
}a[MAXN];
int visit[MAXN];
int head[MAXN], cnt;
struct seg{
int y, next;
}e[MAXM];
void add_edge(int x, int y) {
e[++cnt].y = y;
e[cnt].next = head[x];
head[x] = cnt;
}
void dfs1(int x, int fa) {
a[x].deep = a[fa].deep + 1;
a[x].fa = fa;
a[x].size = 1;
for(int i = head[x]; i; i = e[i].next)
if(e[i].y != fa) {
dfs1(e[i].y , x);
a[x].size += a[e[i].y].size ;
a[x].son = a[a[x].son].size > a[e[i].y].size ? a[x].son : e[i].y;
}
}
void dfs2(int x, int tp) {
a[x].tp = tp;
if(a[x].son) dfs2(a[x].son , tp);
for(int i = head[x]; i; i = e[i].next)
if(e[i].y != a[x].fa && e[i].y != a[x].son) {
dfs2(e[i].y, e[i].y);
}
}
int lca(int x, int y) {
while(a[x].tp != a[y].tp) {
if(a[a[x].tp].deep < a[a[y].tp].deep) swap(x, y);
x = a[a[x].tp].fa;
}
return a[x].deep < a[y].deep ? x : y;
}
void dfs3(int x) {
if(a[x].son == 0) {
a[x].tag += a[x].cf;
// printf("tag_%d : %d\n",x, a[x].tag);
return ;
}
for(int i = head[x]; i; i = e[i].next)
if(e[i].y != a[x].fa) {
dfs3(e[i].y);
a[x].tag += a[e[i].y].tag ;
}
a[x].tag += a[x].cf ;//实际上还要在后面写上a[x].ans = ....
//但这题木有初值,所以我就直接用tag了
// printf("tag_%d : %d\n",x, a[x].tag);
}
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i++) scanf("%d",&visit[i]);
int x,y;
for(int i = 1; i < n; i++) {
scanf("%d%d",&x, &y);
add_edge(x,y);
add_edge(y,x);
}
dfs1(1, 0);
dfs2(1, 1);
int Lca;
for(int i = 1; i < n; i++) {
a[visit[i]].cf++;
a[visit[i+1]].cf++;
Lca = lca(visit[i], visit[i+1]);
a[Lca].cf--;
a[a[Lca].fa].cf--;
}
dfs3(1);
for(int i = 2; i <= n; i++) a[visit[i]].tag--;
for(int i = 1; i <= n; i++) printf("%d\n",a[i].tag);
// for(int i = 1; i <= n; i++) printf("cf_%d : %d\n",i, a[i].cf);
return 0;
}
/*
5
1 4 5 3 2
1 2
2 4
2 3
4 5
*/
luoguP3258 [JLOI2014]松鼠的新家的更多相关文章
- luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)
P3258 [JLOI2014]松鼠的新家 题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...
- [luoguP3258] [JLOI2014]松鼠的新家(lca + 树上差分)
传送门 需要把一条路径上除了终点外的所有数都 + 1, 比如,给路径 s - t 上的权值 + 1,可以先求 x = lca(s,t) 类似数列上差分的思路,可以给 s 和 f[t] 的权值 + 1, ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 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根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...
- [Luogu 3258] JLOI2014 松鼠的新家
[Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...
随机推荐
- CheckBoxList选中某项,获取其它项是否是选中
<div class="formControls col-xs-8 col-sm-9" style="margin-top:-15px;" id=&quo ...
- Python 3 线程模型,进程模型记录
最近需要使用 python3 多线程处理大型数据,顺道探究了一下,python3 的线程模型的情况,下面进行简要记录: 多线程运行的优点: 使用线程可以把程序中占用时间较长的任务放到后台去处理: 用户 ...
- 《2018:skymind.ai 发布了一份非常全面的开源数据集》
这是一份非常全面的开源数据集,你,真的不想要吗? 近期,skymind.ai 发布了一份非常全面的开源数据集.内容包括生物识别.自然图像以及深度学习图像等数据集,现机器之心将其整理如下:(内附链接 ...
- Redis高可用集群-哨兵模式(Redis-Sentinel)
前言 Redis哨兵模式,用现在流行的话可以说就是一个“哨兵机器人”,给“哨兵机器人”进行相应的配置之后,这个"机器人"可以7*24小时工作,它能能够自动帮助你做一些事情,如监控 ...
- Shell(1)---变量
Shell(1)---变量 初衷:学习shell的目的很简单,自己经常在linux服务器上做各种操作,而且基本上是一些相同的命令操作,所以就想通过shell脚本来启动就行,能够节省一定的开发时间,提高 ...
- PDF目录编辑器使用介绍
PDF目录编辑器使用介绍 魏刘宏 2019.06.28 PDF 是一个比较优秀的文档格式,能够保证在任何终端显示的样式是一样的.但同时也带来了一个问题,就是编辑不方便,其实这也是这个格式特意为之的,无 ...
- C# WinForm实现禁止最大化、最小化、双击标题栏、双击图标等操作
protected override void WndProc(ref Message m) { if (m.Msg==0x112) { switch ((int) m.WParam) { //禁止双 ...
- python3的reload(sys)
import sys reload(sys) sys.setdefaultencoding(‘utf-8’) 以上是python2的写法,但是在python3中这个需要已经不存在了,这么做也不会什么实 ...
- Python【day 17-2】面向对象-成员
'''''' ''' 1.简述面向对象三大特性并用示例解释说明?[背写] 1.封装 狭义的封装:把一组属性封装到一个对象,创建对象的时候 广义的封装:代码块,函数.对象.类.模块-py文件都是封装 把 ...
- java主函数
相信很多初次接触java的同学,在遇见主函数的时候,听到最多的就是主函数的格式是固定的,不能进行修改等等.这就让人疑惑了,主函数为啥就那么特殊呢?接下来博主会为大家解释主函数.大家先看看下面这个程序: ...