Problem5735--学习系列——线段树 I —— 建立线段树

5735: 学习系列——线段树 I —— 建立线段树

[Creator : ]
Time Limit : 1.000 sec  Memory Limit : 256 MiB

Description

【背景知识】
在很多算法题目中常有的操作有:
1、update,更新某个位置的数据:使用普通数组,这个操作的时间复杂度我们可以控制在 $O(1)$。
2、query,查询从 $[L,\ R]$ 的数据和:使用普通数据,这个操作的时间复杂度为 $O(n)$。
如果我们需要进行 $m$ 次 update 和 query 操作,我们可以看到,时间复杂度的瓶颈在 query 操作。也许你已经学过了前缀和,使用前缀和,我们可以将 query 操作降低到 $O(1)$,但是很不幸,update 操作的时间复杂度就是上升到 $O(n)$。
线段树这个数据结构,我们可以将 update 和 query 的时间复杂度都控制在 $O(logn)$,这样,我们可以提升算法的效率。
这样,我们总时间复杂度将会是 $O(m*logn)$。
线段树是一棵二叉树,线段树上每个结点对应的是序列的一段区间,每一个叶子结点对应的是序列的一个元素。树上的每个节点都维护一个区间,根维护的是整个区间,每个节点维护的是父亲的区间二等分后的其中一个子区间。
线段树首先是一个完全二叉树。
有一个数组为 $[1,\ 2,\ 3,\ 4,\ 5]$,我们建立的线段树如下图所示。

对应的线段树建树过程,如下图所示。

对于任何一个长度为 $n$ 的数组,对应的线段树大小为 $1+2+4+⋯+2^{⌈log_2n⌉}=2^{⌈log_2n⌉+1}<4n$,对应的二叉树的深度为 $O(logn)$。

【任务】
从上面解析,我们可以看出线段树是一个完整二叉树。上图中没有叶子结点的地方,我们会在对应的位置补零。
我们的第一个任务就是根据给出长度为 $n$ 的数组 $a$,构建对应的线段树。
完成本任务,你应该已经掌握了建立线段树的知识。

Input

第一行一个整数 $n\ (1 \leq n \leq 10^4)$,表示数组的大小。
第二行包括 $n$ 个数字,每个数字 $-10^4 \leq a_i \leq 10^4$。两个数字用空格隔开。

Output

一行包括 $4*n$ 个整数,表示对应的完整线段树。

Sample 1 Input

5
1 3 -2 8 -7

Sample 1 Output

3 2 1 4 -2 8 -7 1 3 0 0 0 0 0 0 0 0 0 0 0

Sample 2 Input

6
1 3 5 7 9 11

Sample 2 Output

36 9 27 4 5 16 11 1 3 0 0 7 9 0 0 0 0 0 0 0 0 0 0 0

Source/Category

数据结构 2.9.线段树