参考学习资源

  • 【电子科技大学】树状数组与ST表

点击查看【bilibili】

  • LeetCode315题解

    正文

    基本介绍

    树状数组是用来解决动态前缀和的数据结构。

image.png

构造树状数组

由于树状数组的底层是数组,所以需要先构造一个数组的结构。树状数组主要有两个操作:update和query。
update操作表示向树状数组中更新一个元素
query操作表示向树状数组中查询

lowbit操作 => 找到右边第一个1

x & (-x) 或者 x & (~x + 1)

应用场景

  • 区间和:[5,8] = sum(8) - sum(4)
  • 单点查询:对区间[3,6]中的元素都加上5
    • 由于是求前缀和,所以相当于3到6的时候加上5的影响,6之后去除5的影响即可。(没懂,遇到例题再看吧)

代码实现:

  1. /**
  2. * 树状数组实现
  3. */
  4. public class BinaryIndexTree {
  5. private final int length; // 树状数组的长度
  6. private final int[] data; // 树状数组底层存储(从第1位开始存储)
  7. public BinaryIndexTree(int length) {
  8. this.length = length;
  9. this.data = new int[length + 1];
  10. }
  11. /**
  12. * lowbit操作实现,也可以写成 x & (~x + 1)
  13. *
  14. * @param x
  15. * @return
  16. */
  17. public int lowbit(int x) {
  18. return x & (-x);
  19. }
  20. /**
  21. * 向树状数组查询i之前的前缀和
  22. *
  23. * @param i
  24. * @return
  25. */
  26. public int query(int i) {
  27. int res = 0;
  28. while (i > 0) {
  29. res += this.data[i];
  30. i -= lowbit(i);
  31. }
  32. return res;
  33. }
  34. /**
  35. * 更新树状数组第i位的值
  36. *
  37. * @param i
  38. * @param delta
  39. */
  40. public void update(int i, int delta) {
  41. while (i <= this.length) {
  42. data[i] += delta;
  43. i += lowbit(i);
  44. }
  45. }
  46. }