首页 > 其他分享 >线段树合并复杂度证明

线段树合并复杂度证明

时间:2024-06-04 19:00:15浏览次数:23  
标签:merge 复杂度 合并 节点 访问 线段

以CF600E为例,没看过题目的先去看题。
本题的线段树做法,即对题目所给树中每个结点所在子树建树维护数字出现情况。此做法中,当前节点和其兄弟节点对应的线段树需要合并到父节点上,最后父节点上权值update到新树。也就是说对于每个非叶子节点,其有x个子节点,就要合并x次(其实也可以看成x-1次,第一次是合并到空节点上,复杂度忽略不计)。
画出线段树结构示意图,如下

首先区分开做法中update和merge的复杂度,update不用谈,稳定logn复杂度。
对于merge复杂度,我们考虑线段树上每个节点,分析每个节点在所有merge操作可能被访问多少次即可。
对于线段树上第一层节点,即根节点,如图

合并两树不为空时,一定会访问一次这个节点。其实更抽象一点,只要合并的两棵树同时包含了这个节点的子孙,那么这个节点非访问不可。既然他是根节点,那每次合并都要访问他了,所以线段树上的根节点在O(N)次合并中,会被访问O(N)次。
考虑第二层左边的节点

它对应了最底层左边四个节点,放在题目中的意义就是1-4这四种颜色,所以如果两棵树同时有1-4颜色中的一种,那么这个节点要选。
现在结合题目给出树讨论什么时候在哪些节点需要访问这个节点。
下面是题目所给树的一个可能情形

特意标黑的节点表示属于1-4颜色的节点,现思考什么地方合并会访问到第二层左边的节点。
首先1号黑点和2号黑点不存在合并操作,他们的复杂度已经在update贡献中计算过了。从3号黑点往上看,因为3号点的兄弟没有一个是1-4颜色的,所以他们的合并过程不会访问线段树左半边的任何点。接下来到合并到3号黑点的父节点,由于4号节点的颜色是1-4,两线段树都同时存在线段树左半边的节点,最起码2号点一定在两颗线段树中重叠了,所以也贡献一次复杂度。而再上去,如果兄弟节点都是白色,且它们的子树中都不含黑色节点的话,那么这个节点就不会对合并过程贡献复杂度。
到这里已经有点显然了,这个节点对于merge操作的复杂度贡献最多为O(黑点个数-1)。读者可以试试用归纳法去证明一下?
再考虑线段树第二层右边节点的复杂度,同理,就是O(4-8颜色的节点个数-1)。
重点来了,有没有可能,这两组节点有相交的空间呢?
当然没可能,除非一个节点有两个颜色。
所以线段树第二层节点对merge操作的复杂度贡献,同样为O(N)。
到此想必已非常明了,线段树每一层对merge操作的复杂度贡献都为O(N)。
一共logn层,总复杂度为O(NlogN)。

标签:merge,复杂度,合并,节点,访问,线段
From: https://www.cnblogs.com/nectarl/p/18231515

相关文章

  • 对相同的key中的value进行合并
    //假设ccmdbCarWeizis是一个包含CarWeizi对象的列表ccmdbCarWeizis.forEach(carWeizi->{//提取CarWeizi对象的carInformation属性的前三个字符作为省份简称Stringlabel=carWeizi.getCarInformation().substring(0,3);//检查groupedMap是否已......
  • 字符串的应用---合并
    准备:publicclassEmployee{publicintId{get;set;}publicstringName{get;set;}publicdoubleSalary{get;set;}}publicclassSeat{publicintId{get;set;}publ......
  • 详解和实现数据表格中的行数据合并功能
    theme:smartblue前言需求场景:在提供了数据查看和修改的表格视图中(如table、a-table等…),允许用户自行选择多行数据,依据当前状态进行特定列数据的合并操作。选中的数据将统一显示为选中组的首条数据值。同时,页面会即时反馈显示合并后的效果,提供直观的操作反馈。效果......
  • 在MySQL中,你可以使用动态SQL和存储过程来根据元数据表查询多个表,并将结果集合并。以下
    DELIMITER$$CREATEPROCEDUREMergeDataFromTables()BEGIN--游标声明DECLAREdoneINTDEFAULTFALSE;DECLAREtbl_nameVARCHAR(255);DECLAREcurCURSORFORSELECT表明FROMtable_col;DECLARECONTINUEHANDLERFORNOTFOUNDSETdone=TRU......
  • jacoco覆盖率多版本exec合并
    @目录概要概要所有代码已经上传到gitee,仓库地址:https://gitee.com/chen_zai_xing/jacoco。方法指令合并参考ray大佬的https://blog.csdn.net/tushuping/article/details/131640959?spm=1001.2014.3001.5502,大佬在文中未提及指令签名带上指令相对于方法中的序号,这里补充说明下。......
  • iview table 表头单元格合并
    <Tableborder:columns="cusColumns":data="cusData"></Table>cusColumns:[{title:'门店/节点',align:'center',//fixed:'left',minWidth:100,render:(h,para......
  • 【Git 版本管理】合并 + 变更,看懂Git
    看懂Git合并操作分离HEAD分离HEAD测试相对引用(^||~)操作符^相对引用^测试操作符~相对引用~测试撤销变更GitResetGitRevert撤销变更测试整理提交记录GitCherry-pick测试交互式rebase交互式rebase测试合并操作关键字:commit、branch、merge、......
  • 代码随想录算法训练营第二十天 | 654.最大二叉树 617.合并二叉树 二叉搜索树
    654.最大二叉树题目链接文章讲解视频讲解classSolution{public:TreeNode*constructMaximumBinaryTree(vector<int>&nums){returninorderTraversal(nums,0,nums.size()-1);}TreeNode*inorderTraversal(vector<int>&nums,intbegi......
  • 【模板】线段树
    #include<iostream>#defineintlonglongusingnamespacestd;constintMAXX=1e5+11;inta[MAXX];structnode{ intl,r,sum,add;//add为懒标记}tree[MAXX*4];voidpushup(intpos){ tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;}......
  • canvas 合并图片和文字
    代码asyncgetImgInfo(img,text){returnnewPromise((resolve,reject)=>{constcanvas=document.createElement("canvas");canvas.width=52;canvas.height=68;constctx=canvas.getContext("2d");......