基本思想

树链剖分一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每条边属于且只属于一条链,然后再通过数据结构来维护每一条链。

一些定义

树链:树上的路径.

剖分:把路径分类为重链和轻链.

重儿子:u的子节点中siz[v]值最大的v.

轻儿子:u的其它子节点.

重边:点u与其重儿子的连边.

轻边:点u与其轻儿子的连边.

重链:由重边连成的路径.

轻链:轻边.

性质

  1. 如果(u,v)为轻边,则siz[v]$\times$2<siz[u].
  2. 从根到某一点的路径上轻链、重链的个数都不大于log$\;$n.
  3. 树剖序其实也可以是dfs序的一种.

实现

一些变量:

f[u]表示u的父亲.

siz[u]表示以u为根的子树的大小.

dep[u]表示u的深度(根深度为1).

top[u]表示u所在的链的顶端节点.

son[u]表示与u的重儿子.

重标号:

p[u]:重标号后u的编号.

dfs序:dfs的时候先走重边.

这样可以使得重边的编号是连续的,方便维护.

  • 用两遍dfs求出所需的所有变量以及重标号.
int f[N],p[N],dep[N],siz[N],son[N],top[N];
/*top[u]:u所在的链的顶端节点,son[u]:u的重儿子*/
inline void dfs1(int u){int m=0;siz[u]=1;for(int i=g[u];i;i=e[i].nxt)if(!dep[e[i].to]){f[e[i].to]=u;dep[e[i].to]=dep[u]+1;dfs1(e[i].to);siz[u]+=siz[e[i].to];if(siz[e[i].to]>m){son[u]=e[i].to;m=siz[e[i].to];}}
}
inline void dfs2(int u,int tp){top[u]=tp;p[u]=++cnt;ww[cnt]=w[u];if(son[u]) dfs2(son[u],tp);for(int i=g[u];i;i=e[i].nxt){if(e[i].to!=f[u]&&e[i].to!=son[u])dfs2(e[i].to,e[i].to);}
}

  • 访问修改(u,v):

类似倍增的走法,每次将深度大的往上移,直到u,v属于同一条链.

inline int sum(int x,int y){int ret=0,t;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]){t=x;x=y;y=t;}ret+=ask(1,p[top[x]],p[x]);x=f[top[x]];}if(p[x]>p[y]){t=x;x=y;y=t;}ret+=ask(1,p[x],p[y]);return ret;
}

inline void change(int x,int y,int k){int t;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]){t=x;x=y;y=t;}cover(1,p[top[x]],p[x],k);x=f[top[x]];}if(p[x]>p[y]){t=x;x=y;y=t;}cover(1,p[x],p[y],k);
}

转载于:https://www.cnblogs.com/AireenYe/p/6219160.html

[学习笔记]树链剖分相关推荐

  1. 树链剖分入门+HYSBZ - 1036树的统计Count

    今天学习了树链剖分,记录一下. [题目背景] HYSBZ - 1036树的统计Count [题目分析] 题目要求求任意结点之间路径的和以及路径上最大的结点,还有可能修改.如果正常做可能会很复杂(我也不 ...

  2. SPOJ 375 树链剖分学习

    学习树链剖分的第一题,第二个dfs忘记递归了(太蠢),re了两发,改过来以后就1A了. 学习树链剖分可以参考这篇博客:http://blog.sina.com.cn/s/blog_7a17468201 ...

  3. POJ 3237 树链剖分学习(树链剖分小结)

    一个地方wa了3发,找了一组数组发现的错误,太蠢,就是两个人数作交换写成了 a=b ,b=a.最近智商真是感人.这道题是由spoj375这题改编的,多了一个取反的操作,这个操作只需要多维护一个最小值就 ...

  4. 树链剖分(入门学习)

    学习博客:https://www.cnblogs.com/ivanovcraft/p/9019090.html 先来回顾两个问题: 1,将树从x到y结点最短路径上所有节点的值都加上z 这也是个模板题了 ...

  5. 对LCA、树上倍增、树链剖分(重链剖分长链剖分)和LCT(Link-Cut Tree)的学习

    LCA what is LCA & what can LCA do LCA(Lowest Common Ancestors),即最近公共祖先 在一棵树上,两个节点的深度最浅的公共祖先就是 L ...

  6. 【暖*墟】#树链剖分# 树链剖分学习与练习

    树链剖分 树链剖分是一种优化,将树上最常经过的几条链划为重点,用线段树来优化区间修改和查询. 并且因为在一棵子树中dfs序是连续的,并且在任意一条重链上,dfs序也是连续的, 可以认为轻链是单点修改, ...

  7. SPOJ 375. Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...

  8. POJ 3237 Tree (树链剖分)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 2825   Accepted: 769 Description ...

  9. hdu 5274(树链剖分)

    解题思路:这道题据说是树链剖分,所以也学习了一下. http://blog.sina.com.cn/s/blog_7a1746820100wp67.html 不同的是这里是点权值,我按照相似的处理方式 ...

最新文章

  1. c语言中副作用和顺序点的理解
  2. 代理模式(Proxy)简介
  3. Nginx Keepalived安装部署完整步骤
  4. 3.AngularJS-过滤器
  5. 【No.7 C++对象的构造与析构时间】
  6. 从Commons CLI迁移到picocli
  7. xgboost实例_XGBoost超详细推导,终于有人讲明白了!
  8. 虚拟世界来自现实世界,同时又促进现实世界
  9. SpringBoot2.x 同个文件的加载顺序,静态资源文件
  10. Github Star 9.7K,超级好用的OCR数据合成与半自动标注工具,强烈推荐!
  11. 10年老电脑如何提速_2020年10月和双十一轻薄本/轻薄型笔记本电脑如何挑选?内含轻薄本/轻薄型笔记本电脑推荐!...
  12. Matlab使用for循环将多个行向量合成一个行向量或者一个多维矩阵
  13. spring boot项目搭建 连接数据库完成项目基础架构布局
  14. CMDN Club每周精选(第2期)
  15. SPSS之配对样本的T检验
  16. 常用的页面布局(两栏布局、三栏(圣杯、双飞翼)布局)
  17. ProxySQL 排错 Max connect timeout reached while reaching hostgroup 10 after 10000ms
  18. linux 检查openssl,linux – 如何检查OpenSSL中的FIPS 140-2支持?
  19. java吸血鬼数字_吸血鬼数字的简单实现
  20. 地图飞线图 echart+高德地图实现

热门文章

  1. 一篇来自前端同学对后端接口的吐槽:痛!
  2. 源码读不会,小白两行泪!
  3. 徒手撸一个简单的 IOC
  4. Spring Boot 注册 Servlet 的3种方式
  5. Java枚举:小小enum,优雅而干净
  6. 程序员也得懂点儿理财知识
  7. 设计模式之单例模式实践
  8. [RabbitMQ+Python入门经典] 兔子和兔子窝
  9. Java 线程池艺术探索
  10. AutoBench+Httperf的安装、测试