树状数组

来源:互联网 发布:gear软件下载 编辑:程序博客网 时间:2024/05/24 05:09

太晚了,不整了,找个时间再整

会长的模板

#include<cstdio>#include<cstring>#define lowerBit(x) (x&(-x))int num[10000];int n;void UpDate(int x,int y)//把第x个数加y{while (x <= n){num[x] += y;x = x+lowerBit(x);}}int Query(int x)//求从1到x的和 {int sum = 0;while (x > 0){sum += num[x];x = x-lowerBit(x);//x&(x-1)}return sum;}int main(){scanf ("%d",&n);memset(num,0,sizeof(num));for (int i = 1 ; i <= n ; i++){int t;scanf ("%d",&t);UpDate(i,t);}int m;scanf ("%d",&m);while (m--){int x,y;scanf ("%d %d",&x,&y);printf ("%d\n",Query(y)-Query(x-1));}return 0;}

求区间和

1.    sum[i]        从num[1]+...+num[i]的和       O(1)
2.    线段数                                     O(logn)
3.    树状数组                                 O(logn)

区别:
1.线段数和树状数组可以修改,而前缀和不能修改。
2.树状数组空间复杂度较低。


求lowerBit

第一种: x&(-x)int x=0000000000000001010100-x -> 1000000000000001010100  ->反码  111111...11110101011   ->加1   11111111110101100反码加1为补码 00000000000000010101001111111111111110101100&-----------------------0000000000000000000100第二种:x-(x&(x-1))int x=000000000000000101010000000000000000010101000000000000000001010011&-----------------------000000000000000101000000000000000000010101000000000000000001010000------------------------0000000000000000000100