首页 > 其他分享 >【学习笔记】树链剖分

【学习笔记】树链剖分

时间:2024-04-10 21:37:19浏览次数:29  
标签:ma 剖分 int top 笔记 树链 maxi 重链 节点

一、重链剖分

1. 定义 & 作用

树链剖分用于解决在树上执行的操作,将树上操作变为区间操作。用区间来维护。

2. 主要思想 & 实现

有一棵树

然后,我们把边区分一下,有一些边是“重边”,其余的是“轻边”,像这样:(红边为重边,黑边为轻)

重边和轻边如何确定呢?看每一个结点旁的红色数字,代表他的子节点个数,每一个节点连向自己子节点最多的儿子的那条边即为重边了。

然后许多个连在一起的重边就组合在一起,被称为重链。重链的顶端为这条重链中深度最低的节点。实现的话,就把代码按上面的那样打就好了。只需要对于每一个节点,记录这个节点所在的重链的顶端。为 \(top_x\)。放上代码吧。

void cut(int x,int topx)
{
	id[x]=++fx;
	top[x]=topx;
	if(sons[x]==1)
	{
		ma[x]=id[x];
		return;
	}
	int maxi=0;
	for(int i=first[x];i;i=e[i].next)
	{
		int to=e[i].to;
		if(to==fa[x])continue;
		if(sons[to]>sons[maxi])
			maxi=to;
	}
	cut(maxi,topx);
	ma[x]=max(ma[x],ma[maxi]);
	for(int i=first[x];i;i=e[i].next)
	{
		int to=e[i].to;
		if(to==fa[x]||to==maxi)
			continue;
		cut(to,to);
		ma[x]=max(ma[x],ma[to]);
	}
}

二、重链剖分的常见用途

1. 重链剖分求LCA

很简单。对于两个需要求 LCA 的节点,假设为 \(x\) 和 \(y\),判断 \(top_x\) 和 \(top_y\) 哪个深度深,就把节点往上跳。即将这个节点设为自己 \(top\) 的父亲。反复执行,直到这两个节点在同一条重链上。

int lca(int a,int b)
{
    while(top[a]!=top[b])
    {
        if(dep[top[a]]>dep[top[b]])
        	a=fa[top[a]];
        else b=fa[top[b]];
    }
    if(dep[a]<dep[b]) return a;
    else return b;
}

2. 一些树上操作

我们根据重边先,轻边后的顺序遍历整棵树,以此打上编号,像这样:

蓝色数字为编号。这时可以发现一个东西,就是很多操作所涉及的所有结点都是连续的。比如说对自己子节点的操作......还有一些操作,是由一个个重链组成的,而每一条重链的编号是连续的,那可以开一个线段树,很多操作进行时,边跳(不断使得当前节点成为自己 \(top\) 的父亲)边改变节点们的值。详见模板 软件包管理器

标签:ma,剖分,int,top,笔记,树链,maxi,重链,节点
From: https://www.cnblogs.com/WindChime/p/18127507

相关文章

  • 【学习笔记】好题
    常来看看。Antiluna好闪,拜谢Antiluna。1.奖金每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元,且必须是整数。1≤n≤10000,1≤m≤20000。......
  • 【学习笔记】dijkstra
    一、dijkstra1.定义&作用很简单。一个单源最短路算法。2.思想&实现我觉得sm的图已经够了。二、堆优化dijkstra1.先来认识一下proirity_queue2.如何使用proirity_queue对dijkstra优化?每一步,我们都需要找到\(d\)值最小的节点(即\(......
  • 【学习笔记】spfa
    一、spfa模板:voidspfa(intx){ for(inti=1;i<=n;i++) vis[i]=0,dis[i]=inf; dis[1]=0,f[1]=1; q.push(1); while(!q.empty()) { intt=q.front(); q.pop(); vis[t]=0; for(inti=first[t];i;i=e[i].next) { intto=e[i].to; if(dis[t]+e[i].v<......
  • 【学习笔记】并查集
    一、普通并查集1.定义&作用并查集是管理元素分组的算法,可以高效对元素分组(合并为一组)以及查询两个元素是否在一组。2.主要思想&实现对于每一个组,设置一个“组长”,每一次合并时只需要将其中一组的组长设为另一组的组长,查询时只需要查询组长是否相同。每一个组都可以理解......
  • SQL SERVER 从入门到精通 第5版 第二篇 第9章 视图的使用 读书笔记
      第9章视图的使用视图是一种常用的数据库对象,它将查询的结果以虚拟表的形式存储在数据中,视图并不在数据库中以存储数据集的形式存在.视图的结构和内容是建立在对表的查询基础之上的,和表一样包括行和列,这些行,列数据都来源于其所引用的表,并且是在引用视图过程中动......
  • 《C++程序设计》阅读笔记【7-堆和拷贝构造函数】
    ......
  • 机器学习和深度学习--李宏毅(笔记与个人理解)Day9
    Day9LogisticRegression(内涵,熵和交叉熵的详解)中间打了一天的gta5,图书馆闭馆正好+npy不舒服那天+天气不好,哈哈哈哈哈总之各种理由吧,导致昨天没弄起来,今天补更!这里重点注意一下,这个output值是概率哈,也就是说式子整体表示的含义是x属于c1的概率是多大这个老师......
  • python初学者笔记(7)——求和函数总结
    python经常要用到各种求和,例如列表求和,元素求和,利用函数求和,将这些方法总结发给大家!1.python两个数的求和函数defsum_2_num(num1,num2):result=num1+num2returnresult#必须在执行行输入,函数命名后必须调用,调用sum_2_num(),或者print()#sum_2_num(10,20......
  • SQL SERVER 从入门到精通 第5版 第二篇 第8章 SQL数据高级查询 读书笔记
     第8章SQL数据高级查询 >.子查询与嵌套查询>.子查询概述:子查询是一个嵌套在SELECT,INSERT,UPDATE和DELETE语句或者其他子查询中的查询,任何允许使用表达式的地方都可以使用子查询.子查询语法规则如下:>.子查询的SELECT查询总使用圆括号......
  • 个人博客项目笔记_05
    1.ThreadLocal内存泄漏ThreadLocal内存泄漏是指由于没有及时清理ThreadLocal实例所存储的数据,导致这些数据在线程池或长时间运行的应用中累积过多,最终导致内存占用过高的情况。内存泄漏通常发生在以下情况下:线程池场景下的ThreadLocal使用不当:在使用线程池时,如果线程......