首页 > 其他分享 >浅谈全局平衡二叉树

浅谈全局平衡二叉树

时间:2023-04-19 18:46:54浏览次数:51  
标签:LCT log 复杂度 mid GBT 二叉树 全局 浅谈

首先,这个是GBT,不是GPT。其次,那个是ChatGPT,不是ChatGBT。

原理

我们先考虑一个经典的问题:单点修树上最大权独立集问题,也就是Luogu P4719 【模板】"动态 DP"&动态树分治

使用树剖维护矩阵可以做到 \(O(n\log^2n)\) 的复杂度,可以通过 \(10^5\) 的数据。
那我们能不能把这个问题优化成 \(O(n\log n)\) 的呢?其实很简单,换成LCT,复杂度就是 \(O(n\log n)\) 的了,但是常数巨大……

我们发现在这类问题里面我们并没有使用LCT最核心的部分——断连边,而是使用了它 \(O(\log n)\) 提取树上链的特性。所以我们考虑把LCT换成静态的树结构以减小常数,于是全局平衡二叉树(Global Balance Tree)就诞生了,这也就是GBT有时会被称作静态LCT的原因。

我们考虑对于每一个条重链建一个BST,保证其中序遍历是链上从浅到深的顺序,轻链的连接方式和LCT一样,将每个BST的根的父亲定义为这个子树的链顶的父亲,也就是“认父不认子”。

对于一条到根的链的信息维护,就是不断跳父亲的过程,只需要在这过程中每个节点进行之多一次左孩子修改和当前节点修改即可。这样做一次的复杂度就是 \(O(dep\times S)\) 的,其中 \(dep\) 为树深度,\(S\) 为单次修改复杂度。

现在我们的问题就是如何保证 \(dep\) 是 \(O(\log n)\) 的。

参考树剖的复杂度证明,我们希望每跳 \(O(1)\) 次父亲就可以使的树的大小至少翻倍。比如说在跳轻链的时候,根据重链剖分的性质,树大小至少翻倍的。

于是,我们考虑给每一个点赋一个权值:所有轻儿子子树大小和+1。然后每次找到带权中点 \(mid\) 作为根,再递归处理 \([l,mid-1]\) 和 \([mid+1,r]\) 即可。不难发现这样子,在每个链的BST中跳一次,树的大小也是至少翻倍的。

这样,我们单次修改或者查找就是 \(O(\log n)\) 的了。

\(O(n\log n)\) 建树代码,其中 \(sum\) 数组为点权的前缀和:

int build_GBT(int l,int r)
{
    if(r<l) return 0;
    int mid=lower_bound(sum+l,sum+r+1,sum[r]+sum[l-1]>>1)-sum;
    if(s[mid].lson=build_GBT(l,mid-1)) s[s[mid].lson].fa=mid;
    if(s[mid].rson=build_GBT(mid+1,r)) s[s[mid].rson].fa=mid;
    s[mid].num=jz[mid];
    update(mid);
    return mid;
}

例题

感觉例题难点都是如何变成链上维护的问题,GBT都是用来替代重链剖分的……

Luogu P4751 【模板】"动态DP"&动态树分治(加强版)

单点修树上最大权独立集问题,\(n\leqslant 10^6,m\leqslant 3\times 10^6\)。

Luogu P9168 [省选联考 2023] 人员调度

后记

其实感觉实现很优秀的树剖是可以冲过去的。

标签:LCT,log,复杂度,mid,GBT,二叉树,全局,浅谈
From: https://www.cnblogs.com/Xun-Xiaoyao/p/17334219.html

相关文章

  • 云计算与网络计算、全局计算、互联网计算等相比,有哪些特点,具有哪些优势?
    IT专业家将云计算与网络计算、全局计算、互联网计算等相比,归纳出云计算的以下特点。1.以用户为中心的界面,云计算的界面不需要用户改变他们的工作习惯和环境(编程语言、编绎器、操作系统等);需要在本地安装的云计算客户端是轻量级的,比如NimbusCloudkit客户端只有15MB;云计算......
  • LeetCode Top100: 翻转二叉树(python)
    给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例1:输入:root=[4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1]示例2:输入:root=[2,1,3]输出:[2,3,1]示例3:输入:root=[]输出:[] 提示:树中节点数目范围在 [0,100] 内-100<=Node.val<=100实......
  • LeetCode Top 100: 二叉树的直径 (python)
     给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。 示例:给定二叉树1/\23/\45返回 3,它的长度是路径[4,2,1,3]......
  • 4月18日leetcode二叉树几种遍历方式的非递归和递归
    给你二叉树的根节点 root ,返回它节点值的 前序 遍历。 示例1:二叉树的前序中序和后序遍历算法是学习二叉树必不可少的,若是使用c语言遍历前中后序还是比较繁琐的,因为要考虑遍历结果存放的序列大小问题,想要解决这个问题就得想用递归计算二叉树的节点数量,再调用递归子函数完......
  • 23-4-18--二叉树--完全二叉树的层序遍历
    一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 D 的,有 N 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就是完全二叉树。给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果。输入格式:......
  • 节点与其祖先之间的最大差值(树,二叉树,深度优先搜索)
    1、节点与其祖先之间的最大差值(难度中等)给定二叉树的根节点root,找出存在于不同节点A和B之间的最大值V,其中V=|A.val-B.val|,且A是B的祖先。(如果A的任何子节点之一为B,或者A的任何子节点是B的祖先,那么我们认为A是B的祖先)/***Definitionforabinary......
  • 二叉树前序遍历,中序遍历,后序遍历的统一模板写法【递归和非递归】
    二叉树有三种深度遍历的方式,分别是前序,中序和后序,分别对应LeetCode的144,94,145三道题目。三种遍历方式的递归写法都差不多,也比较容易,相信大家都已经烂熟于心了。但是非递归写法,目前还有很多不同的写法,比如循环条件,有的用栈是否为空,有的用指针是否指向NULL。这样比较混乱的形式,不利于......
  • 浅谈离线数据倾斜
    作者:京东零售 荆明岚一、数据倾斜的基本概念1、什么是数据倾斜?用最通俗易懂的话来说,数据倾斜无非就是大量的相同key被partition分配到一个分区里,造成了'一个人累死,其他人闲死'的情况,这种情况是我们不能接受的,这也违背了并行计算的初衷,首先一个节点要承受着巨大的压力,而其他......
  • 4月17日leetcode二叉树的层序遍历II
    给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)(出自力扣)这个昨天的二叉树的层序遍历有所不同:需要将从后往前层序遍历二叉树,其实很简单,只需要用vector的逆置函数,将vector中的vector逆置即可。这里顺便......
  • LeetCode Top100: 二叉树的最大深度 (python)
     给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7],3/\920/\157返回它的最大深度 3。 以下是Python代码实现:cl......