树上差分

树上差分分析

使点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]松鼠的新家的更多相关文章

  1. luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)

    P3258 [JLOI2014]松鼠的新家  题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...

  2. [luoguP3258] [JLOI2014]松鼠的新家(lca + 树上差分)

    传送门 需要把一条路径上除了终点外的所有数都 + 1, 比如,给路径 s - t 上的权值 + 1,可以先求 x = lca(s,t) 类似数列上差分的思路,可以给 s 和 f[t] 的权值 + 1, ...

  3. BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )

    裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...

  4. 3631: [JLOI2014]松鼠的新家

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 707  Solved: 342[Submit][Statu ...

  5. [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)

    今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...

  6. P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...

  7. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  8. 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家

    [题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...

  9. [Luogu 3258] JLOI2014 松鼠的新家

    [Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...

随机推荐

  1. 初级模拟电路:3-8 BJT数据规格书(直流部分)

    回到目录 本小节我们以2N4123通用型BJT硅基晶体管为例,来介绍如何阅读BJT的数据规格书,点此链接可以阅读和下载2N4123的数据规格书. 1. 总体性能 打开datasheet后,首先看标题: ...

  2. MATLAB实例:为匹配真实标签,对训练得到的标签进行调整

    MATLAB实例:为匹配真实标签,对训练得到的标签进行调整 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. MATLAB程序 munkres.m ...

  3. jt格式文件与3D数据压缩

    介绍 JT是西门子公司推出的PLM通用三维格式,设计为一个开放.高效率的.紧凑,持久性存储的产品数据格式,用于产品可视化.协作和CAD数据共享.JT文件格式包括多方面的数据,以及对曲面边的精准表示,产 ...

  4. 第6次作业--static关键字、对象

    题目1:编写一个类Computer,类中含有一个求n的阶乘的方法.将该类打包,并在另一包中的Java文件App.java中引入包,在主类中定义Computer类的对象,调用求n的阶乘的方法(n值由参数 ...

  5. 201871010106-丁宣元 《面向对象程序设计(java)》第一周学习总结

    丁宣元 <面向对象程序设计(java)>第一周学习总结 正文开头 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在 ...

  6. 去掉Oracle数据库中字段值前后空格

    发现oracle字段钟包含了空格,可能是前空格,也可能是后空格,因为是历史数据,需要特殊处理.但是中间的空格可能是一些特殊人员的姓名含有,这种情况不能处理.所以我们只需要处理前后空格即可.使用如下sq ...

  7. 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 1

    如今的项目开发中,接口是很普遍的应用技术.现在好多项目组都单独设有接口开发人员.像腾讯.微博.淘宝等开放平台,其所谓的开放,就是提供一些可调用的接口,用于获取相关的信息.例如,微信用户基本信息.淘宝店 ...

  8. 07-selenium、PhantomJS(无头浏览器)

    selenium(自动化测试工具可用于在爬虫中解决js动态加载问题) 简介(本质就是模仿浏览器工作) Selenium 是什么?一句话,自动化测试工具.它支持各种浏览器,包括 Chrome,Safar ...

  9. Springboot整合Thmeleaf

    1.概述 Thymeleaf类似JSP.Velocity.Freemarker都是模板引擎,主要用来展示数据,原理如下 springboot官网还是推荐使用Thymeleaf而不是jsp, 不使用js ...

  10. Spring MVC整合FreeMarker

    什么是Freemarker?    FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或 ...