zoukankan      html  css  js  c++  java
  • 树状数组

    看到树状数组后觉得这个数据结构很优美,比较有意思,虽然很多时候线段树能做,但树状数组内存消耗更小,思想也很有意思,就想记录一下

     看上去是比较漂亮的,A[] 是序列的实际数值, C[] 记录的是某一段A[]的和,例如 C[4]就是 sun(1--4)。

    先介绍个很关键的函数:int lowbit(int x){return x&(-x);} 这个可以返回二进制数 x 中最低位的 1 还是 1 ,其余都为 0 的数,比如对于 1000(8的二进制) 1000=100+lowbit(100)=110+lowbit(110)=111+lowbit(111);

    其实 C[i] 有很多性质:

    1,将 i 化为二进制,比如 i = 6 = 110 那么 lowbit(6) = 2 ,代表 C[6] 记录了 2 个数的和, lowbit(7)=1 ,所以 C[7] 记录的 1 个数的和,所以查询时 i-lowbit(i) 会到 C[i] 恰好没覆盖到的地方

    2,C[i]的父节点是 C[i+lowbit(i)],也就是说,i+lowbit(i) 是记录了 i 记录的前缀和的,所以更新时要不断向父节点更新。

    看懂了这些再看看代码,很容易理解了

     求区间和O(log n),便于单点更新,区间查询:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 
     5 using namespace std;
     6 #define MAXN 1000
     7 
     8 int n;
     9 int A[MAXN];
    10 int C[MAXN];
    11 
    12 int lowbit(int x)
    13 {
    14     return x&(-x);
    15 }
    16 
    17 void update(int x,int add) //A[x]增减
    18 {
    19     while (x<=n)
    20     {
    21         C[x]+=add;
    22         x+=lowbit(x);
    23     }
    24 }
    25 
    26 void new_tree(int n)   //建树,直接利用update
    27 {
    28     memset(C,0,sizeof(C));
    29     for (int i=1;i<=n;i++)
    30         update(i,A[i]);
    31 }
    32 
    33 int getsum(int x)//[1--x]的和
    34 {
    35     int sum=0;
    36     while(x>0)
    37     {
    38         sum+=C[x];
    39         x -= lowbit(x); //性质1
    40     }
    41     return sum;
    42 }
    43 
    44 int main()
    45 {
    46     scanf("%d",&n);
    47     for (int i=1;i<=n;i++)
    48         scanf("%d",&A[i]);
    49     new_tree(n);
    50 
    51     int l,r;
    52     scanf("%d %d",&l,&r);
    53     printf("%d
    ",getsum(r)-getsum(l-1)); //l--r 的和
    54 
    55     return 0;
    56 }
    View Code

     虽然用前缀和求区间和是O(1),但是不便更新

    树状数组还可以很方便的做区间更新,单点查询,更新时 update(L,v),update(R+1,-v) ,查询为 get_sum(i), 即可,还是因为树状数组保存的是前缀和的原因

     还可以升级到多维的,很厉害

  • 相关阅读:
    tensorflow学习笔记五----------逻辑回归
    tensorflow学习笔记四----------构造线性回归模型
    tensorflow学习笔记三----------基本操作
    tensorflow学习笔记二----------变量
    tensorflow学习笔记一----------tensorflow安装
    大屏某区域滚动效果循环
    echarts轨迹图,各个城市线路图轨迹如何取值
    react组件,样式添加的方法
    微信小程序中hidden属性不生效
    react组件渲染编程html不成功
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6657393.html
Copyright © 2011-2022 走看看