树状数组(搬运自维基百科)

本文介绍了树状数组(Fenwick_tree)的基本概念及其在高效计算数列前缀和中的应用。主要内容包括树状数组的创建、修改及求和操作的具体实现方法,并提供了lowbit求法的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树状数组(Fenwick_tree),最早由Peter M. Fenwick于1994年以A New Data Structure for Cumulative Frequency Tables为题发表在SOFTWARE PRACTICE AND EXPERIENCE。其初衷是解决数据压缩里的累积频率(Cumulative Frequency)的计算问题,现多用于高效计算数列的前缀和。它可以以O(\log n)的时间得到\sum_{i=1}^N a[i],并同样以O(\log n)对某项加一个常数。

基本操作:

  1)新建;

  2)修改;

  3)求和;

 

lowbit求法:

int lowbit(int x)
{
    return x&(-x);
}

 

新建:

定义一个数组 BIT,用以维护A的前缀和,则:

BIT_i=\sum_{i=i-lowbit(i)+1}^{i}A_i

具体能用以下方式实现:

void build()
{
    for (int i=1;i<=MAX_N;i++)
    {
        BIT[i]=A[i];
        for (int j=i-1; j>i-lowbit(i); j--)
            BIT[i]+=A[j];
    }
}

修改:

假设现在要将A[i]的值增加delta,

那么,需要将BIT[i]覆盖的区间包含A[i]的值都加上K.

这个过程可以写成递归,或者普通的循环.

需要计算的次数与数据规模N的二进制位数有关,即这部分的时间复杂度是O(LogN)

void edit(int i, int delta)
{
    for (int j = i; j <= MAX_N; j += lowbit(j))
        BIT[j] += delta;
}

求和:

假设我们需要计算\sum_{i=1}^{k}A_i的值.

  1. 首先,将ans初始化为0,将i计为k.
  2. 将ans的值加上BIT[P]
  3. 将i的值减去lowbit(i)
  4. 重复步骤2~3,直到i的值变为0
int sum (int k)
{
    int ans = 0;
    for (int i = k; i > 0; i -= lowbit(i))
        ans += BIT[i];
    return ans;
}

 

转载于:https://www.cnblogs.com/yoyo-sincerely/p/5374889.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值