树状数组

Binary Index Tree 美其名曰 树状数组
那到底是树呢😃 还是数组呢😂 从严格意义上来说 其实它就是数组 但是绝非普通
废话不说 放张图再说废话🤣
它强大就强大在 对于区间问题 不管是单点修改 还是区间求和 算法复杂度都为 log ⁡ ( n ) \log(n) log(n)级别。

在这里插入图片描述
从图中可以清楚看到 它就是数组只不过存储的内容不太一样,满足一下的递推式
我们假设原数组是最下面一行,新建一个数组C来存储原数组的内容
c [ 1 ] = a [ 1 ] c[1]=a[1] c[1]=a[1]
c [ 2 ] = c [ 1 ] + a [ 2 ] c[2]=c[1]+a[2] c[2]=c[1]+a[2]
c [ 3 ] = a [ 3 ] c[3]=a[3] c[3]=a[3]
c [ 4 ] = c [ 2 ] + c [ 3 ] + a [ 4 ] c[4]=c[2]+c[3]+a[4] c[4]=c[2]+c[3]+a[4]
c [ 5 ] = a [ 5 ] c[5]=a[5] c[5]=a[5]
c [ 6 ] = c [ 5 ] + a [ 6 ] c[6]=c[5]+a[6] c[6]=c[5]+a[6]
c [ 7 ] = a [ 7 ] c[7]=a[7] c[7]=a[7]
c [ 8 ] = c [ 4 ] + c [ 6 ] + c [ 7 ] + a [ 8 ] c[8]=c[4]+c[6]+c[7]+a[8] c[8]=c[4]+c[6]+c[7]+a[8]
c [ 9 ] = a [ 9 ] c[9]=a[9] c[9]=a[9]
c [ 10 ] = c [ 9 ] + a [ 10 ] c[10]=c[9]+a[10] c[10]=c[9]+a[10]
这种关系看得我云里雾里的,完全不知道怎么来的,怎么办。放弃😒 不 世界这么大,这么玄妙的数据结构怎么能放过呢。
下面说点实际的,能不能构造出这样的数组C
或者怎么给C数组赋初值呢 大家可以再看看上面的两张图 再结合下面的代码

单点修改
void update(int x,int k){
     while(x<=n){
         tree[x]+=k;
         x+=lowbit(x);
     }
}
区间求和
int sum(int x){
    int ret=0;
    while(x>0){
        ret+=tree[x];
        x-=lowbit(x);
    }
}

首先呢 先将原数组更新到数组C ,其实就相当于把将各项都为0的数组修改为K 时间复杂度为 O ( n log ⁡ ( n ) ) O(n\log(n)) O(nlog(n)) 循环n次 完成n次单点修改。
接下来 进行单点修改和区间求和 都是 O ( log ⁡ ( n ) ) O(\log(n)) O(log(n))的。所以总的复杂度为 n log ⁡ ( n ) n\log(n) nlog(n)
这里作个对比 如果要求
1.对某个区间的每个数 加上k 2.输出第n个数的值 估计差不多也是 n log ⁡ ( n ) n\log(n) nlog(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值