树状数组模板

首先要分清a[] c[] sum[] 他们各自所代表的意思;

a[]就是输入的数组;

c[]就是建立的树状数组;

c[i] = a[i - 2^k +1] + ...... + a[i];

a有多少个c就有多少个,而且c[i]肯定包含相应的a[i];

lowbit(i) = 2^k 表示i的二进制数表示形式留下左右边的1其余为取0得到的数

sum[k] = c[N1] + c[N2] + c[N3].......+ c[Nm];

Ni-1 = Ni - lowbit(i);

求和的话,就是有c[Nm]  c[Nm-1]  c[Nm-2] .... c[N1]的过程 Ni - lowbit(i)的过程是将Ni的二进制的最右边的1去掉的过程,所以求和的时间复杂度为O(log(k));

而更新也是如果a[i]更新了 那么c[N1] c[N2] ..... C[Nm]也要更新N1= i; 就是从 c[N1] c[N2] ... c[Nm]的过程 Ni = Ni-1 + lowbit(i);就是在Ni - 1的二进制最右边1后边填1的过程,就是在时间复杂度也是O(log(n))级别。

适用于:单点更新,区间求和;

lowbite操作:

int lowbit(int x)
{
   //return x^(x&(x - 1));
    return x&(-x);
}

modify操作单点的更新

void modify(int pos,int sc)//位置pos更新sc
{
    while (pos <= n)//由C[N1]到C[Nm]的过程
    {
        c[pos] += sc;
        pos += lowbit(pos);
    }
}

getsum操作区间求和

int getsum(int pos)
{
    int sum = 0;
    while (pos > 0)//由C[Nm]到C[N1]的过程
    {
        sum += c[pos];
        pos -= lowbit(pos);
    }
    return sum;
}

  

posted @ 2012-07-30 15:07  E_star  阅读(234)  评论(0编辑  收藏  举报