树链剖分
2016-05-20 19:16
218 查看
关于链剖
链剖实质上是通过轻重链的划分,将树剖成一条条重链,首尾相连存进数据结构(线段树、树状数组、splay之类的),支持路径查询,修改等如何实现?
定义以下几种东西重儿子 子树大小最大的儿子
轻儿子 除重儿子其他的都是轻儿子
重边 每个点连向它的重儿子的边
轻边 连向轻儿子的边
重链 重边组成的链
这里总共有5条重链,1-2-4-8、5、9、3-6-10、7
我们按照优先重链的DFS序重新标号,用DFN[]数组记录,例如DFN[8]=4,DFN[7]=10
定义几个数组top[],son[],deep[],size[],分别表示所在重链顶端,重儿子编号,深度,子树大小
我们可以一次DFS求出son[],deep[],sizep[]
再一次DFS求出top[],dfn[],这两个DFS非常简单,自己随便YY一下
然后就可以根据DFN的顺序依次丢进数据结构里面。
重点在于,如何路径修改和路径查询
一般的都是要做一个LCA的,然而链剖并不需要
设当前要修改的路径起点u,终点v
如果u,v在同一条重链上,即top[u]=top[v],那么可以直接在数据结构上区间修改dfn[u]到dfn[v]这一段。
如果u,v不在同一条重链上,需要比较deep[top[u]],deep[top[v]]
不妨总是使deep[top[u]]>=deep[top[v]],不是的话就交换
那么我们区间修改dfn[top[u]]到dfn[u],再把u跳到father[top[u]]
重复操作,直到u=v
查询也是一样的。
复杂度是O(Nlog2N)的
下面有一个例题
[ZJOI2008][JZOJ2256][BZOJ1036]树的统计
代码见这里
相关文章推荐
- Python 进阶 —— 迭代器与生成器
- 【原】iOS学习之Swift之语法1(精简版)
- 如何把Android手机变成一个WIFI下载热点? — 报文转发及DNS报文拦截
- jQuery中登录友好提示系列(1)
- 页面自动的分页 跳转
- lua 小数点后面几位
- mongodb
- gson-2.2.api简单
- Fiddler 教程
- HDU 3999 The order of a Tree
- 使用iptables防火墙限制web的访问PV
- unbuntu下清理磁盘空间
- PHP Yii框架过滤器用法详解
- spring boot:repository thymeleaf postgresql java程(五):存在问题分析
- eclipse内存设置,tomcat内存设置,查看内存大小
- NYOJ - 16 矩形嵌套
- MySQL入门--登陆数据库、显示客户端的所有数据库、使用指定数据库、显示指定数据库中的所有数据表、
- 这些年微软相关的技术总结, Javascript在客户端的使用
- Android之Activity启动和结束方法-无传递结果数据
- 第八界中国云计算大会---简单回忆