树状数组模板

本文介绍了如何使用树状数组优化区间和计算,通过lowbit函数划分数组,展示添加和查询操作,以及在元素改变时更新集合的方法,提高数据结构的效率。
摘要由CSDN通过智能技术生成

在对一个数列求区间和时,我们通常采用前缀和来完成,但如果修改其中某值,就需要将所有后面前缀和修改,这是非常麻烦的,那么就可以用树状数组。

树状数组原理大致就是将基础元素合并成越来越大的集合,修改则只需修改集合值即可,避免的具体对每个前缀操作。

首先我们来了解一下这个函数

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

这个函数就是求t最低位为1和其后零的十进制

如10010 就是 二进制的10 十进制的2

那么为什么要用这个呢?

如果让 x+=lowbit(x);

比如1 2 4 8 16 32...

这是不是可以将该数组划分成不同部分

对int 最多就32 个层

可以看这样一个图

数组中偶数位保存是一个个的和,奇数的lowbit是1,减去就变成前面偶数所包含的集合

代码实现:

先输入初始数组

for(int i=1;i<=n;i++) scanf("%d",&dp[i]);

再初始化树状数组

void add(int t,int u){
    for(int i=t;i<=n;i+=lowbit(i)) v[i]+=u;
}
void init(){
    for(int i=1;i<=n;i++) add(i,dp[i]);
}

如果求和left到right,传入查找left应减一,因为是是[left,right]闭区间

int sums(int t){
    int res=0;
    for(int i=t;i>0;i-=lowbit(i)) res+=v[i];
    return res;
}

主代码
cout<<sums(y)-sums(x-1)<<endl;

若元素改变,则改变包含他的集合

t为下标,u为增加的值


for(int i=t;i<=n;i+=lowbit(i)) v[i]+=u;

谢谢观看!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值