树状数组模板
首先要分清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; }