全局平衡二叉树

这篇博客探讨了如何通过全局平衡二叉树优化树剖和LCT的数据结构。作者指出,传统的树剖方法在处理重链时可能会导致O(logl)的时间复杂度,而LCT的常数过大。为解决这些问题,提出了使用平衡树维护重链,并根据轻儿子的大小调整树的形态,以达到O(logn)的总复杂度。QTREE IV 全局平衡二叉树是一种实现这种优化的解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于链分治。
每次不仅要处理轻儿子到每个点的贡献,重链中的互相贡献也需要计算。
对于树剖,每条链上它是用一个线段树来维护贡献的。但是复杂度还是O(log⁡l)O(\log l)O(logl),如果出题人把lllhhh(重链长度和深度)平均一下,那么就可以被卡成O(log⁡2n)O(\log^2 n)O(log2n)
对于LCT,我们很难处理它过大的常数。
那么我们还是考虑树剖。
仔细分析可以发现线段树维护是有一点浪费的,
如果有一个点轻儿子总sizesizesize过大,那么仍然把这个点雪藏在其重链所在线段树最后一层是不优的。
我们可以用平衡树来维护一条重链然后把这个点放在平衡树根的位置。
可是现在还是O(log⁡2n)O(\log^2 n)O(log2n)的。
我们可以沿用这个思想,把平衡树的形态偏向轻儿子sizesizesize大的一方。
具体方法为:

对于一条重链,每个点的权值设为它的轻儿子的sizesizesize之和+1(加不加一不重要,只是这样好算:val=sz[x]−sz[sonx]val=sz[x]−sz[sonx]val=sz[x]sz[sonx],找到带权重心后,把它作为这一层结点,递归左右区间建立左右儿子。
重链之间的虚边按照原树形态建就好了。
考虑这样建出来的树,每次向上跳一次(虚边/实边),轻儿子的总sizesizesize至少翻一倍,所以树高是log⁡n\log nlogn的。

所以就是每条重链我们不按它的重心来分治,我们按加上子树sizesizesize的带权重心来分治,这样可以得到总O(log⁡n)O(\log n)O(logn)的优秀复杂度。

QTREE IV 全局平衡二叉树解法:

#include<bits/stdc++.h>
#define maxn 100005
#define inf 0x3f3f3f3f
using namespace std;
 
int info[maxn],Prev[maxn<<1],to[maxn<<1],cst[maxn<<1],cnt_e;
void Node(int u,int v,int c){
   
    Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=c; }
 
int n,m;
 
int val[maxn],sum[maxn],lm[maxn],rm[maxn],mx[maxn],fa[maxn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值