• 是什么?
    将树的所有边剖分成重边和轻边从而便于维护边权信息和进行修改,应对一系列大数据树上修改查询问题。
  • 为什么?
    如果不进行剖分代价会很大:对树上边(u,v)中的边权查询修改,必然要将边权建立成搜索树或查询树进行维护,对于所有边建立后对于(u,v)修改时只能将(u,v)中所有边进行遍历修改,最坏代价(退化成链)为n*查询修改代价。而如果把(u,v)中的边变成连续的一段区间,就会大大降低时间代价。
  • 怎么做?
    {正常的题解在这里都会下一堆定义,什么重边重孩子,我觉得不容易理解}
    想把(u,v)这条边变成一段可以查找的连续区间,一定要对边进行一个重新的分类和排序,对于检索也会有要求,如果我不能把(u,v)变成一段全连续的区间,但是如果能变成几部分也是很好的。
    而相对理想的就是变成log2nlog_2n个区间。
    有的人说树链剖分就是把树边hash到log2nlog_2n个区间上。
    下面我只能开始下定义了(由于本人才疏学浅,没法证明根到某一点中轻重边不大于log2nlog_2n,也没法证明这个是怎么想到的)

  • 首先记:
    节点n子树节点数个数size[n];
    节点n深度deep[n];
    节点n父节点fa[n];

  • 重孩子:儿子节点所有孩子中size最大的;
  • 轻孩子:儿子节点中除了重儿子的;
  • 重边:连接重儿子的边;
  • 轻边:连接轻儿子的边;
  • 重链:重边连成的链;
  • 轻链:轻边连成的链;

  • 再定义:
    hson[n]表示n的重儿子标号;
    top[n]表示n在的重链的顶节点,不在重链上为自己标号。
    id[n]表示剖分后的节点标号;

  • 性质
    从根节点到任意节点路径上轻重边数量不大于log2nlog_2n(别问我为什么);

  • 实现方法
    其实很简单,第一遍跑一遍dfs求出刚才说的size,deep,hson;
    然后再一遍dfs求出top,id;
    对应id算出val[id]表示id这个点下面连的边的权值。
    对val建检索树,排序树。

  • 重点
    查询的时候这么查:
    对(n,v)这条边:
    如果n,v在一条重边上,就直接查询(id[n],id[v])这一段区间即可。
    如果你,v不在一条重边上,就尽量向一条重边上靠,查询(id[n],id[top[n]]),n再跳到fa[top[n]]上,继续做,知道fa[top[n]]与v在一条重链上,就回到了上一种情况。
    这里也有一些细节,因为题中往往给的边都不是按深度给的,所以对于u,v,要注意深度关系,进行交换

好了,这样我们就成功解决了对树上修改查询边权或点的问题。

下面放上代码:

vector<int> v[MAXN];
int size[MAXN],dep[MAXN],val[MAXN],id[MAXN],hson[MAXN],top[MAXN],fa[MAXN];//定义
int edge=1,num=1;
struct tree{int x,y,z;void init(){scanf("%d%d%d",&x,&y,&z);}
}e[MAXN];//起点重点权值
void dfs1(int d,int f,int u){//d:深度 f:父节点 u:当前节点dep[u]=d;size[u]=1;hson[u]=0;fa[u]=f;for(vector<int>::iterator it=v[u].begin();it!=v[u].end();it++){if(*it==f) continue;dfs1(d+1,u,*it);size[u]+=size[*it];if(size[hson[u]]<size[*it])hson[u]=*it;//找重儿子}
}
void dfs2(int u,int tp){top[u]=tp;//赋值topid[u]=num++;//赋值idif(hson[u]) dfs2(hson[u],tp);//优先重儿子for(vector<int>::iterator it=v[u].begin();it!=v[u].end();it++){if(*it==fa[u]||*it==hson[u]) continue;dfs2(*it,*it);}
}

赋值val:节点与父亲的边

for(int i=1;i<n;i++){  if(dep[e[i].x]<dep[e[i].y])swap(e[i].x, e[i].y);  val[id[e[i].x]] = e[i].z;
}  

查询:只要不在一条重链上,(深度大的)就向父节点靠

int find(int u,int v){int t1=top[u],t2=top[v];int ans=0;while(t1!=t2){if(dep[t1]<dep[t2]){swap(t1,t2);swap(u,v);}ans=max(query(1,id[t1],id[u]),ans);u=fa[t1];t1=top[u];}if(u==v) return ans;if (dep[u] > dep[v]) swap(u, v);  ans = max(query(1,id[hson[u]], id[v]), ans);  return ans;
}

val就用线段树平衡树维护一下就行了,这里就不附代码。

【树链剖分】树链剖分讲解相关推荐

  1. 树链剖分之重链剖分详解

    树链剖分之重链剖分详解 一些概念 算法讲解 应用 求最近公共祖先 对树上的一条链进行修改和查询 相关练习题 一些概念 在学习重链剖分前,首先要明白以下几个概念: 中二重儿子:就是一个节点的儿子中最&q ...

  2. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释...

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  3. 【bzoj1146】 [CTSC2008]网络管理Network【树链剖分+树套树+二分 线段树套Treap】

    1146: [CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公 ...

  4. 【bzoj 3531】 [Sdoi2014]旅行(树链剖分+树套树)

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1197  Solved: 576 [Submit][Statu ...

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

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

  6. 树链剖分中的重链剖分

    更多文章可以在本人的个人小站:https://kaiserwilheim.github.io 查看. 转载请注明出处. 引言 树链剖分(简称"树剖",又称"重链剖分&qu ...

  7. 树链剖分(轻重链剖分)

    树链剖分,是一种将树剖分为链,在链上进行各种操作以达到目的的算法.树链剖分(轻重链剖分)可以解决lca(最近公共祖先),树上操作(对树上两点及经过的路的权值进行求和,修改等操作)等一类操作.对于这些问 ...

  8. 树链剖分——轻重链剖分

    2022年01月27日,第十三天 1. 题目链接:P3384 [模板]轻重链剖分/树链剖分 思路:树链剖分直接搞,时间复杂度为 O(nlog2n)O(nlog^2n)O(nlog2n) ,通过模板题, ...

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

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

  10. 磁盘存储链式的B树与B+树

    磁盘存储链式的B树与B+树 前言 磁盘结构分析与数据存储原理 B树的定义 B树与B+树的区别 B树插入的两种分裂 非根结点分裂 根结点分裂 插入分裂代码 B树删除的前后借位与节点合并 关键字在叶子结点 ...

最新文章

  1. 一文读懂卷积神经网络CNN(学习笔记)
  2. 全世界都认为汉语是婴儿语(转载)
  3. python2必须安装步骤_Python入门-第三方库的安装及环境配置(2)
  4. iOS -OC调用js页面
  5. Linux上线程开发API概要(线程)
  6. Pycharm 专业版 导入系统pip安装的包
  7. maven asm 依赖配置_Maven教程_v20201119
  8. tidyr | 对数据框分行或分列进行嵌套操作
  9. 是什么原因让你选择做程序员
  10. 机器学习:神经网络之表达
  11. 带ant 的收发器_ANT无线收发器nRF24AP1及其应用
  12. java中mvc框架有哪些,MVC框架详解,框架到底是什么? | 学步园
  13. mysql导出csv 分隔符_导出到CSV文件,CSV文件好像是以逗号为分隔符的吧?如果数据库字段里含有逗号怎么处理?比如说下面这个字...
  14. 教你炒股票21:缠中说禅买卖点分析的完备性
  15. (个人)AR电子书系统创新实训第三周(1)
  16. 统计学名词解释 —— 3. 「简单随机样本」、「联合分布」与「联合密度」
  17. FFMPEG开发之——视频转码
  18. 为什么我要弃用Snapchat?
  19. Web大学生网页作业成品——个人班级网站设计与实现(HTML+CSS)
  20. mybatis批量新增和批量更新的效率对比

热门文章

  1. Git 详细安装教程(详解 Git 安装过程的每一个步骤)
  2. c语言遗传算法百度云,遗传算法c语言程序.doc
  3. Linux 镜像挂载
  4. gimp中文版教程_Gimp中文经典入门实用教程.pdf
  5. linux下查看已经安装的jdk 并卸载jdk的方法
  6. Android 性能分析工具介绍
  7. 常用的linux巡检命令,linux常用巡检命令
  8. Linux 常用 shell 命令
  9. Word中的Visio图直接转换为图片
  10. 远程控制软件teamview好用么?