目录
一、线段树简介
1、导入线段树
如题,已知一个长度为 N 的数列,共有 M 次操作,每次操作读入 X
X==1 读入 L,R,K,将区间 [L,R] 每个数加上 K。
X==2 读入 L,R,求出区间 [L,R] 每个数的和。
这是洛谷的P3372,在你没学线段树之前,有两种很简单地方法:
方法一 | 方法二 | |
名称 | 暴力 | 前缀和 |
区间加 k | O(1) | O(R-L+1) |
区间求和 | O(R-L+1) | O(1) |
这两种方法总有一个操作花的时间会很大,因此我们需要一个能使两个操作时间平衡的数据结构——线段树。
2、线段树的存储
线段树的每个节点都是这样的:
其中 p 表示该结点编号,L,R表示下标,dat 表示 [L,R] 的区间和,而 p 的左子树编好为 2p ,右子树编号为 2p+1 ,p 所代表的 [L,R] 区间又被分成了两个一样大的区间,被左右子树所表示,那么 p 点的区间和就等于左右子树的区间和。
根据上述所示,那么这七个数 2 5 1 6 4 7 3 存进一棵线段树就长这样:
一棵有 n 的节点的线段树是一颗深度为(简称 k)的二叉搜索树,第 k-1 层有 个节点,所以前 k-1 层是 个节点,第 k 层则有个节点,所以一共要×个节点