首页 > 其他分享 >树分治相关

树分治相关

时间:2024-01-30 15:33:39浏览次数:30  
标签:结点 处理 分治 tnd link 相关 树上

树分治相关

一种特别的分治思想,但难点不在于点分治思想本身。

有板子,但是板子跟题目重点几乎无关。

点分治 淀粉质

用途

用于处理树上多对点询问或寻找有条件最远(最近)点对。主要是处理多对点对。

做法

我们先选择一个节点作为根节点 \(rt\) ,所有完全位于其子树中的路径可以分为两种,一种是经过当前根节点的路径,一种是不经过当前根节点的路径。前一种我们在这次分治中得到,后面一种在之后的分治中计算,就转化为了第一种路径。

考虑枚举分治中心 \(rt\) 的子节点 \(u\) ,对于经过 \(rt\) 的路径上的所有点 \(v\) ,\(u\) 都要与其计算一次贡献,可以得出 \(v\)的点集 是 \(rt\) 不包含 \(u\) 的子树的子树中所有点。

一般我们考虑容斥或不计算 \(u\) 子树内结点与 \(u\) 产生的额外(或者错误)贡献。

选取分治中心为每次分治后的树的重心,总处理结点数量为\(O(nlogn)\)

树的重心用一个简单树型dp求。

处理方法与难点:

跟分块一样,分治之后处理是一大问题。常见的处理方式有两种:

  • 套用数据结构,对于每个分治中心维护一个动态的数据结构(如动态开点线段树,平衡树),直接区间查询修改处理子树内贡献
  • 利用排序+二分或双指针,将数据有序化并尽快找到所需的区间端点。

两种方法各有优缺。

对于套用数据结构,会增加 \(logn\) 级别的常数,此外一般需要支持动态开点保证不爆空间。

对于双指针,要注意扫描一次序列时间复杂度是 \(O(L)\) 的,\(L\) 是序列长度。而二分是 \(O(logL)\) 的,如果不是在一次序列中求多对符合要求的区间,尽量使用二分。

离散化和桶排序是点分治中会常用的思想,没思路的时候可以往这两个方面想。如果值域很大桶装不下,可以考虑将权值存出来然后排序。权值相同的元素一定相邻。

难点在于思考出合适的处理方法。实在想不到就乱搞吧

边分治

思路

与上面的点分治类似,我们选取一条边,把树尽量均匀地分成两部分(使边连接的两个子树的 \(size\) 尽量接近)。然后递归处理左右子树,统计信息。

如果是个菊花图,每次断边只会断掉一个结点,所以会被卡成 \(O(n^2)\) ,而二叉树性质很优秀啊(),这时候就需要多叉转二叉(也就是三度化)。

三度化

三度化方式有两种。写法简单的一种是:

把所有儿子依次加一个点串起来

就算把所有点都加一个点串起来,我们也最多增加了 \(n\) 个点, \(n\) 条边,所有复杂度还是同阶的。

新增的点和边要注意他们的值,一般将点权和边权设置为 \(0\) ,也有例外,所以还是根据题目需要来。

可以模拟一下发现,即使分治中心是虚边,也不会存在统计重复的点对。

小细节是因为我们需要知道分治中心边的两端点,所以需要记录是第几条边。于是乎需要用到成对变换来存边。

直观的图

code:

void mkmap(int x,int fa){//三度化(多叉转二叉)
	int tnd=0;
	for(auto it:og[x]){
		if(it.y==fa)continue;
		if(!tnd){
			link(x,it.y,it.w);
			link(it.y,x,it.w);
			tnd=x;//该连接的结点
		}
		else{
			++nn;
			//赋值 !!!
			link(tnd,nn,0);link(nn,tnd,0);//赋值!!!
			link(it.y,tnd,it.w);link(tnd,it.y,it.w);
			tnd=nn;
		}
		mkmap(it.y,x);
	}
}

处理方法/优点

边分治的处理方法比点分治容易,有时候还能省下为了容斥才使用到的数据结构使得复杂度降低码量。

边分治一般不用考虑容斥,一个点在左端点的子树内,那么要统计贡献的点一定都在右端点的子树内。反之同理。所以可以左右子树分开存互不影响。

边分治将每次的分治联通块中的点恰好分成了两部分,这就省去了像点分治那样单独处理以分治重心为路径端点的答案这一过程。

适用/局限

几乎所有点分治的题边分都能做。

局限在于虚点虚边必须不影响答案

点分树(动态点分治):

定义:

点分树是通过更改原树形态使得层数变为\(logn\)级别。

点分治的过程就是构造点分树的过程。将上一层的分治中心 \(u\) 与他的下一层分治中心 \(v\) 连边,重构出一棵虚树。(实际上一般 \(fa_v=u\) 就行)

用途

处理多次询问和带修的点分治问题。并且不会修改操作改变原树的形态(即不会改变每次重心的选取。)

在点分数上向上暴力跳链复杂度是不大于 \(O(logn)\) 的(因为层数不大于 \(O(logn)\) )。

对于任意一个 \(y\),首先在虚树上找到它与 \(x\) 的 \(lca\) 该点必定在原树的 \(x,y\) 路径上。

  • 看不懂的证明:\(lca\) :(或者说囊括连通块同时包含 \(x,y\) 的所有虚树节点中深度最深的那一个),易知在以此点为重心划分子连通块时 \(x,y\)会首次被分割开来

\(x\) 与某个结点在虚树上的 \(lca\) 一定是 \(x\) 的祖先,所以这些点都在 \(x\) 的祖先 除开 \(x\) 的子树的子树上(类似于点分治的味道),因为 \(x\) 的祖先在 \(x\)子树内的结点与\(x\) 的 \(lca\) 不是这个祖先而是 \(x\) 到这个祖先的链上(不含这个祖先)的一个结点。

实现

与点分治板子部分相同。只是多一个建树过程。

处理方法

对于一个点,我们要统计或修改其对所有虚树上祖先的贡献。这个过程可以暴力向上跳完成。

通常我们需要统计虚树上的结点到其虚树上子节点的实树上的信息。实树上的信息与虚树上无关,例如处理虚树上的点到父亲的距离需要在实树上树链剖分求链长。

注意事项

实树上的信息与虚树无关,时刻警惕你需要哪棵树的信息。

关于你自己的注意事项:

看看你统计子树大小的时候有没有递归处理!!!!

标签:结点,处理,分治,tnd,link,相关,树上
From: https://www.cnblogs.com/cmachsocket/p/17997232

相关文章

  • mips交叉编译相关库文件,主要做以后参考
    1.mips交叉编译paho-mqtt3ascmake-DCMAKE_INSTALL_PREFIX=${pwd}/install-DPAHO_WITH_SSL=TRUE-DPAHO_BUILD_SAMPLES=TRUE-DCMAKE_C_COMPILER=/opt/mips-linux-gnueabihf/bin/mips-linux-gnu-gcc-DPAHO_BUILD_DOCUMENTATION=TRUE-DOPENSSL_LIB_SEARCH_PATH=/usr/mips/lib......
  • 12种相关系数汇总!
    所谓相关关系是指2个或2个以上变量取值之间在某种意义下所存在的规律,其目的在于探索数据集所存在隐藏的关系网,在19世纪80年代,Galton通过研究人类身高遗传问题首次提出了相关的概念,文中指出相关关系可以定义为:一个变量变化时,另一个变量或多或少的相应的变量。这种相关关系的统计量......
  • 上辈子推的"分治 NTT"复杂度分析
    hdu7381Cargo式子部分由liuhangxin想出。\[\sum\limits_{i=0}^{n}\binom{k}{i}(n-i)^{k-i}[x^i]\prod\limits_{id=1}^{m}(1-x^{c_{id}})\]实现部分当时胡了一个分治NTT,也不知道时间复杂度为什么是对的,但是过了。AC后十多分钟分析出来这个做法的时间复杂度为\(......
  • docker-compose.yaml相关
    docker-compose.yaml相关Compose和Docker兼容性:Compose文件格式有3个版本,分别为1,2.x和3.x目前主流的为3.x其支持docker1.13.0及其以上的版本常用参数:version#指定compose文件的版本services#定义所有的service信息,......
  • Unity-GC优化相关笔记
    Unity官网GC定义如下创建对象、字符串或数组时,用于存储它的内存是从称为堆的中央池分配的。当此项不再使用时,其先前占用的内存可被回收并用于其他目的。在过去,通常由程序员通过适当的函数调用显式地分配和释放这些堆内存块。如今,Unity的Mono引擎等运行时系统会自动为您管理内......
  • 页面中的blockShow组件展示,可进行相关的样式修改,一般月饼图搭配使用,具体根据实际来
    <template><!--这是新版的相对应的颜色列表的UI--><divclass="bllockListShow"><divclass="pieList"v-for="(item,index)indataArr":key="index"@click="clickUptown(index,item)"......
  • Hutool时间相关工具类的使用
    一、CalendarUtil相关方法:1. calendar(时间):获取Calendar型对象。参数说明:时间:a. 参数为空:获取Calendar的实例对象eg:calendar.get(Calendar.MONTH)b. Date型对象:把Date转为Calendar。c. long型时间戳:转换为Calendar对象,使用当前默认时区。d. long型时间戳,Tim......
  • iOS 17.4 测试版包含大模型相关代码
    外界普遍预计苹果将在6月份通过iOS18推出主要的新人工智能功能。不过根据9to5Mac的报道,他们在iOS17.4第一个测试版中发现的代码表明,苹果正在开发由大语言模型技术支持的Siri新版本,并得到了其他来源的一些帮助。所谓其他来源是指苹果似乎正在使用OpenAI的ChatGPTA......
  • Vue 数据相关实例方法vm.$watch、vm.$set、vm.$delete介绍
    vm.$watch观察vue实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代。//写法一:this.$watch('a.b.c',function(newVal,oldVal){})//键路径vm.$watch(function(){this.fullName=this.......
  • GPS信号的数字接收处理matlab仿真,包括频率点搜索,捕获跟踪,相关峰检测等步骤
    1.算法运行效果图预览 低信噪比下仿真结果如下:  2.算法运行软件版本matlab2022a 3.算法理论概述        GPS(全球定位系统)信号的数字接收处理是GPS接收机核心技术之一,它涉及到从接收到的卫星信号中提取导航数据和解算出位置信息的一系列处理过程。这个......