码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-04-10 19:12:11      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:

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

基本操作:

  1)新建;

  2)修改;

  3)求和;

 

lowbit求法:

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

 

新建:

定义一个数组 BIT,用以维护技术分享的前缀和,则:

技术分享

具体能用以下方式实现:

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];
    }
}

修改:

假设现在要将技术分享的值增加delta,

那么,需要将技术分享覆盖的区间包含技术分享的值都加上K.

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

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

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

求和:

假设我们需要计算技术分享的值.

  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;
}

 

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

标签:

原文地址:http://www.cnblogs.com/yoyo-sincerely/p/5374889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!