Segment Tree & Binary Indexed Tree

Range query when input can be updated(在线修改并查询), otherwise prefixSum should be good enough

  • Segment Tree本质上是一个 Full Binary Tree,每个节点子节点数为0或2

  • 但是每一个segmentTreeNode里存的start(区间左边界), end(区间右边界), val(视题目而定,比如max val)

  • 假设输入数组有N个数,这样Segment Tree就有N个叶子节点,一共有2*N - 1个节点

  • 叶子节点必是长度为1的区间,如[0,0]或[1,1]

  • O(N) time to build tree

  • O(LogN) to query

  • O(LogN) to update

线段树的作用,可以解决的问题

  • 主要问题对象是区间

  • 求区间和,区间最值以及其它区间上的问题

  • 无脑实现3个method

    • buildTree(int start, int end, int[] A)

    • modify(SegmentTreeNode root, int idx, int val)

    • query(SegmentTreeNode root, int start, int end)

问题:给定一个序列,会修改序列上某个位置的数,或是查询区间的和

如果仅涉及区间上的查询,不涉及修改的话,用前缀和即可

修改时间

查询时间

空间

暴力

O(1)

O(N)

O(1)

前缀和

O(N)

O(1)

O(N)

线段树

O(logN)

O(logN)

O(N)

线段数基本操作

  • 最基础的建二叉树,只建左右子树,并没有存max value

  • 这题才是常规的build,要求Node里记住max value

  • 很好的一道dfs的题目

  • 要求区间内的max value

  • 对于每一层的查询,只有两种可能

    • 如果目标区间完全不在root区间内,直接返回(此题返回Int.min)

    • 否则设下一层的有效查询区间为:

      • start = max(query.start, root.start);

      • end = max(query.end, root.end);

    • 然后处理好正确的节点位置,递归查询

  • 要求区间内的value count

  • 注意root可能为null

线段数应用

Range Sum Query

  • 线段树经典应用

  • 熟悉基本操作,模板要熟练

  • 线段数的基本应用

  • 第一遍做的时候有个typo,在queryMin method 里错写成end = Math.min(end, root.end);

  • 20min码完,码字速度着实要加强

Last updated