堆式存储线段树空间大小为4N的证明

文章详细地证明了堆式存储线段树和动态开点线段树的空间大小,指出动态开点线段树空间只需与实际节点数有关,而堆式存储空间与最大节点编号有关。通过数学归纳法展示了线段树的结构特性,如宽度、节点数和树高与更小规模线段树的关系。

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

前言

众所周知,堆式存储线段树空间要开到四倍,动态开点线段树空间要开到二倍。接下来给出证明。

动态开点线段树

动态开点线段树的空间大小只与线段树实际的节点数有关。一般开到2n2n2n

堆式存储线段树

静态线段树一般采用堆式存储,空间与最大节点编号有关。一般开到4n4n4n

证明

定理1

⌊x+12⌋=⌈x2⌉\left\lfloor\frac {x+1}2\right\rfloor=\left\lceil\frac x2\right\rceil2x+1=2x

显然。

定理2

⌊x2⌋+⌈x2⌉=x\left\lfloor\frac {x}2\right\rfloor+\left\lceil\frac x2\right\rceil=x2x+2x=x

显然。

定理3

节点[l,r](l≠r),r−l+1=len[l,r](l\not=r),r-l+1=len[l,r](l=r),rl+1=len的两个子节点分别为[l,⌊l+r2⌋],[⌊l+r2⌋+1,r]\left[l,\left\lfloor\frac{l+r}2\right\rfloor\right],\left[\left\lfloor\frac{l+r}2\right\rfloor+1,r\right][l,2l+r],[2l+r+1,r],其宽度分别为:⌈len2⌉,⌊len2⌋\lceil\frac {len}2\rceil,\lfloor\frac{len}2\rfloor2len,2len

其左区间宽度为:
⌊l+r2⌋−l+1\left\lfloor\frac{l+r}2\right\rfloor-l+12l+rl+1

我们知道:
x−1<⌊x⌋≤xx-1<\lfloor x\rfloor \leq xx1<xx

则:
l+r2−1<⌊l+r2⌋≤l+r2\frac {l+r}2-1<\left\lfloor\frac{l+r}2\right\rfloor\leq \frac{l+r}22l+r1<2l+r2l+r

即:
r−l+22−1<⌊l+r2⌋−l+1≤r−l+22\frac {r-l+2}2-1<\left\lfloor\frac{l+r}2\right\rfloor-l+1\leq \frac{r-l+2}22rl+21<2l+rl+12rl+2

我们还知道:
r−l+22−1<⌊r−l+22⌋≤r−l+22\frac {r-l+2}2-1<\left\lfloor\frac{r-l+2}2\right\rfloor\leq \frac{r-l+2}22rl+21<2rl+22rl+2

(r−l+22−1,r−l+22]\left(\frac {r-l+2}2-1,\frac{r-l+2}2\right](2rl+21,2rl+2]范围内显然只有一个整数,因此
⌊l+r2⌋−l+1=⌊r−l+22⌋=⌈r−l+12⌉=⌈len2⌉\left\lfloor\frac{l+r}2\right\rfloor-l+1=\left\lfloor\frac{r-l+2}2\right\rfloor=\left\lceil\frac{r-l+1}2\right\rceil=\left\lceil\frac{len}2\right\rceil2l+rl+1=2rl+2=2rl+1=2len

同理我们可以得知右区间宽度为len−⌈len2⌉=⌊len2⌋len-\left\lceil\frac{len}2\right\rceil=\lfloor\frac{len}2\rfloorlen2len=2len

定理4

两个线段树。宽度相同则图形态完全相同(区分左右儿子)。

应用数学归纳法容易证明。

定理5

宽度为2k2^k2k的线段树是一颗满二叉树,它的节点数目为2k+1−12^{k+1}-12k+11

首先我们考虑维护区间[1,n=2k][1,n=2^k][1,n=2k]的线段树。

显然它的形态是满二叉树。
那它的节点数量为:∑ki=02i=2k+1−1\underset{i=0}{\overset {k}\sum}2^i=2^{k+1}-1i=0k2i=2k+11

定理6

k=⌈log⁡2n⌉k=\lceil\log_2 n\rceilk=log2n,则有:
⌊n2⌋≤⌊2k2⌋\left\lfloor\frac n2\right\rfloor\leq\left\lfloor\frac {2^k}2\right\rfloor2n22k

⌈n2⌉≤⌈2k2⌉\left\lceil\frac n2\right\rceil\leq\left\lceil\frac {2^k}2\right\rceil2n22k

显然。

定理7

线段树是一个Leafy Tree,即它的一个节点要么没有儿子,要么有左右儿子。

假设一个节点的宽度为len=1len=1len=1,那么它为叶子,若len≠1len\not=1len=1,则它有左右儿子。且根据3可知左右儿子宽度均不为000

定理8

假设根节点深度为000,宽度为nnn的线段树中一个深度为kkk的节点的宽度等于所有下式中的至少一个:
(∘ki=1hi)(n)=(h1∘h2∘...∘hk)(n)\left(\underset{i=1}{\overset k\circ}h_i\right)(n)=(h_1\circ h_2\circ ...\circ h_k )(n)(i=1khi)(n)=(h1h2...hk)(n)

其中hi∈{f,g},f(x≠1)=⌊x2⌋,g(x≠1)=⌈x2⌉h_i\in\{f,g\},f(x\not=1)=\lfloor\frac x2\rfloor,g(x\not=1)=\lceil\frac x2\rceilhi{f,g},f(x=1)=2x,g(x=1)=2x

应用归纳法显然。

定理9

(∘ki=1hi)(x)≤g(k)(y)\left(\underset{i=1}{\overset k\circ}h_i\right)(x)\leq g^{(k)}(y)(i=1khi)(x)g(k)(y),其中x≤yx\leq yxy

应用归纳法显然。

定理10

一颗宽度为2k2^k2k的线段树上一个深度为xxx的节点的宽度可以表示为2k2x=(∘xi=1hi)(2k)\frac{2^k}{2^x}=\left(\underset{i=1}{\overset x\circ}h_i\right)(2^k)2x2k=(i=1xhi)(2k),其中任意hih_ihi可以自由的取到f/gf/gf/g

也就是说此节点宽度对应的hhh序列为所有可能的长度为xxxhhh序列。

也就说明此线段树上存在这样一个深度为xxx的节点,是2k2x=(∘xi=1hi)(2k)\frac{2^k}{2^x}=\left(\underset{i=1}{\overset x\circ}h_i\right)(2^k)2x2k=(i=1xhi)(2k)的必要条件。

这说明存在一组hhh使得2k2x=(∘xi=1hi)(2k)\frac{2^k}{2^x}=\left(\underset{i=1}{\overset x\circ}h_i\right)(2^k)2x2k=(i=1xhi)(2k)是此线段树上存在深度为xxx的节点的充分条件。

应用归纳法显然。

定理11

一颗宽度为nnn的线段树的图形态,是宽度为2k=⌈log⁡2n⌉2^{k=\lceil\log_2{n}\rceil}2k=log2n的线段树图形态的一个包含根节点的生成树(根节点不变)。

这里指的不是同构,而是区分左右儿子方向的完全相同。

证明:
我们考虑线段树,宽度为[1,n][1,n][1,n]

假设线段树中必定存在叶子节点xxx,其深度为d>kd>kd>k

假设存在这样的叶子节点,那我们知道lenx=(∘di=1hi)(n)=1len_x=\left(\underset{i=1}{\overset d\circ}h_i\right)(n)=1lenx=(i=1dhi)(n)=1

则:g(d)(2k)≥(∘di=1hi)(n)=1g^{(d)}(2^k)\geq \left(\underset{i=1}{\overset d\circ}h_i\right)(n)=1g(d)(2k)(i=1dhi)(n)=1

根据10,我们知道,这充分说明在宽度为2k2^k2k的线段树上存在一个节点其深度>k>k>k,这显然是不可能的。因此矛盾。

这说明宽度为nnn的线段树上没有任何一个节点的深度比宽度为2k2^k2k的线段树的节点的深度更大。而宽度为2k2^k2k的线段树是有k+1k+1k+1层节点的满二叉树,所以说明前者没有任何一个部分是后者没有的,因此得证。

定理12

由定理11可知:

宽度为nnn的线段树的节点数,以及树高,均对应小于等于对应的2k2^k2k的线段树。

定理13

2⌈log⁡2n⌉<2n2^{\lceil\log_2n\rceil}< 2n2log2n<2n

证明:
2⌈log⁡2n⌉<2log2n+1=2n2^{\lceil\log_2n\rceil}<2^{log_2n+1}=2n2log2n<2log2n+1=2n

定理14

由5,12,13可知,动态开点线段树最多有2n−12n-12n1个节点,所以空间可以开到2n2n2n

定理15

根节点、图形态和左右儿子方向完全相同的两颗二叉树,在堆式存储中占用的空间位置完全相同。

显然。

定理16

由定理15可知,我们只需要讨论宽度为2k=⌈log⁡2n⌉2^{k=\lceil\log_2n\rceil}2k=log2n的满二叉树的节点编号的最大值即可。

显然这个最大编号为2k+1−12^{k+1}-12k+11,即<4n−1<4n-1<4n1。因此我们就知道了堆式存储二叉树的可能的节点编号最大值小于4n−14n-14n1

后话

原来证明这东西这么麻烦的。

是不是有什么简单方法。

如果您知道请您联系我。

定理17

仿照定理11,容易发现线段树去除了最后一层之后是一个满二叉树。

后记

于是皆大欢喜。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值