树状数组(Binary Indexed Tree)

本文深入讲解了树状数组这一高效数据结构,重点介绍了其在查询前缀和、区间和及单点修改上的应用,时间复杂度为O(nlog_2n)。文章详细解释了树状数组的基本操作,如前缀和查询、单点修改和初始化过程,并提供了经典例题的解析。

特点

树状数组常用于查询前缀和,前缀和通过差分可以得到区间和,并支持单点修改
单点修改和查询前缀和的时间复杂度均为\(O(n\log_2 n)\)

数据结构与基本操作

假定有\(a_1, a_2, ..., a_n\)共n个数,我们使用数组bit[n+1] = {0}, 其中0位置不存储任何信息,仅作为边界判断

i最低位的2的幂
int lowbit(int i){ return i & (-i);}
前缀和
int sum(int i){
    int r = 0;
    while(i > 0){
        r += bit[i];
        i -= lowbit(i)
    }

    return r;
}
单点修改
    void update(int i, int d){
        while(i <= n){
            bit[i] += d;
            i += lowbit(i)
        }
    }
初始化
    for(int i = 0; i < a.size(); i++)
        update(i + 1, a[i]);

经典例题

模板题

307. Range Sum Query - Mutable
493. Reverse Pairs

离散化

315. Count of Smaller Numbers After Self
327. Count of Range Sum

参考

topcoder BIT

转载于:https://www.cnblogs.com/qbits/p/10972651.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值