首页 > 编程语言 > 详细

树状数组模板

时间:2019-05-09 23:16:13      阅读:121      评论:0      收藏:0      [点我收藏+]

树状数组三个核心函数

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

void update(int x,int k){
    for(int i=x;i<=n;i+=lowbit(i)){
        tree[i]+=k;
    }
}

int getsum(int x){
    int sum=0;
    for(int i=x;i>0;i-=lowbit(i)){
        sum+=tree[i];
    }
    return sum;
}

区间求和操作

给定区间[x,y]求其中的每个数的和

sum=getsum(y)-getsum(x-1);

区间加操作

给定区间[x,y]使其中各个数加上k

运用到差分思想:令 b[i] = a[i] - a[i-1] 其中 a[0] = 0;  易证得 a[i] = b[1] + b[2] + b[3] + ... + b[i]

eg:如果 a[5] = {5, 6, 3, 8, 12} 则 b[5] = {5, 1, -3, 5, 4},若在区间[2,4]中每个数都分别加上2得:a[5] = {7, 8, 5, 10, 14} 则 b[5] = {7, 1, -3, 5, 2}

观察可知,若要使得[x,y]中每个数加上k,只需在b[x]上加k,b[y+1]减k即可完成区间加的操作。

int a,now=0;    //now=a[i-1]
for(int i=1;i<=n;++i){
    scanf("%d",&a);
    update(i,a-now);
    now=a;    //更新 
}

update(x,k);
update(y+1,-k);

单点加操作

在数组x的位置加上k

update(x,k);

单点求和

求数组x位置上的值为多少

常规版:

getsum(x)-getsum(x-1)

差分版:

getsum(x);

 

树状数组模板

原文:https://www.cnblogs.com/-Joker/p/10841656.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!