1.线段树:
- 线段树中,叶子节点为数组的元素,线段树中的其他非叶子节点为区间内的最大或者最小/或者总和(根据具体业务而定)
(1)区间染色问题:有一面墙,长度为n,每次选择一段墙染色,m次操作后,问区间[i,k]有多少次颜色。
(2)区间查询
2.线段树的二叉:

平衡二叉树下,二叉搜索不会退化为链表,平衡二叉树的最大深度与最小深度差距不超过1
3.线段树的实现:
采用数组实现:假如有 n 个元素, 则上一层节点有 n / 2 个节点,故需要 4n 空间
// 使用数组实现线段树public class Set<E extends Comparable<E>>{private E[] data;private E[] tree;private Merger<E> merger;public Set(E[] arr, Merger<E> merger){data = (E[]) Object[arr.length];for(int i = 0 ; i < arr.length; i++){data[i] = arr[i];}tree = (E[]) Object[4 * arr.length];// 建立线段树buildSegTree(0, 0, data.length - 1);}public int leftChild(int index){return 2 * index + 1;}public int rightChild(int index){return 2 * index + 2;}public int parent(int index){return index - 1 / 2;}public void buildSegTree(int treeIndex, int l, int r){if(l == r){tree[treeIndex] = data[l];return;}// 每次下一个节点都是 [l, mid][mid + 1, r]int mid = l + (r - l) / 2;buildSegTree(leftChild(treeIndex), l, mid);buildSegTree(rightChild(treeIndex), mid + 1, r);tree[treeIndex] = merger.merge(tree[leftChild(treeIndex)], tree[rightChild(treeIndex)]);}// 区间查询public E Query(int QueryL, int QueryR){if(QueryL < 0 || QueryL >= data.length || QueryR < 0 || QueryR >=data.length){throw new IllegealmentException(" out of index");}E res = Query(0 , 0, data.length, QueryL, QueryR);return res;}// 从 root 开始,在 [0, data.length - 1] 中查询 QueryL ~ QueryRprivate E query(int treeIndex, int l, int r, int QueryL, int QueryR){if(l == QueryL && r == QueryR)return tree[treeIndex];int mid = l + (r - l) / 2;if(QueryR <=mid){return query(leftChild(treeIndex), l, mid, QueryL ,Query R);}else if(QueryL >= mid + 1){return query(rightChild(treeIndex), mid+1, r, QueryL, QueryR);}else{ // QueryL <= mid && QueryR >= midreturn merger.merge(query(leftChild(treeIndex), l, mid, QueryL, mid), query(rightChild(treeIndex), mid+1, r, mid + 1, r));}}// 更改数值,更改数组某index 的元素public void set(int index, E value){if(index < 0 || index >= data.length){throw new IllegalException("out of index");}set(0, 0, data.length - 1, index, value);}public void set(int treeIndex, int l, int r, int index, E value){if(l == r){tree[treeIndex] = value;}int mid = l + (r - l) / 2;if(index >= mid + 1){set(rightChild(treeIndex), mid + 1, r, index, value);}else if(index <= mid){set(leftChild(treeIndex), l, mid, index, value);}tree[treeIndex] = merger.merge(tree[leftchild(treeIndex)], tree[rightchild(treeIndex)]);}}
