为什么线段树要开4倍空间

//定义线段树

struct node
{
    int sum,lazy;
}tree[manx<<2];

在这里插入图片描述
(下面没有讨论公式的证明)
先标几个重点:

  1. 如果区间长度为N,那么构造的线段树的叶子结点个数就是N
  2. 深度为k-1的满二叉树有2k-1 -1个结点,且第k层的节点数是: 2k-1
  3. 假设线段树最后一层的叶子结点为m,倒数第二层叶子结点为n,(n+m=N)
    由1、2可知,线段树结点个数为2(m/2+n)-1+m=2N+1(但是我们开了4N)
  4. 如果一个子树根结点的编号为root, 那么他的左孩子编号为 r o o t 2 root * 2 , 右孩子编号为 r o o t 2 + 1 root * 2+1 (也是因为这个性质,构造线段树需要多开一些空间)
  5. 定义:mid=(l+r)/2;
    tree[root].sum——表示 [l, r] 的区间和
    tree[chl].sum——表示 [l, mid] 的区间和
    tree[chr].sum——表示 [mid+1, r] 的区间和
    (从这里也可以看出,两个区间段要么长度相等,要么右边多一个)

然后讨论需要开的空间大小

  • 最好的情况,就是满二叉树:
    在这里插入图片描述
  • 如果在再加一个结点,(肯定挂在右边)

在这里插入图片描述
上面两种情况都不用开多余的空间,2N-1都可以解决

  • 再加一个,(就挂左边了)
    在这里插入图片描述
    由前面第3点可知,在区间为[1,10]的线段树中,如果我们要访问[6,7]这两个点,就需要在最后一层多开中间的那4个空间,虽然不会用他们储存信息,(如果直接从最左边挨着挂过去,当然2N-1就够了)

从上面也可以看出,如果线段树叶子结点为N个,那么n \leq N
那么根据满二叉树的性质,除“最后一层”,的总结点数 \leq 2N-1
如果“最后一层”开满的话,“最后一层”节点数 \leq 2N
————一共4N-1,所以开4N也一定不会超内存

发布了52 篇原创文章 · 获赞 26 · 访问量 3186

猜你喜欢

转载自blog.csdn.net/qq_43803508/article/details/97501894