树状数组c语言,树状数组/二分索引树(BIT)

本文介绍了树状数组这一数据结构,用于优化在大规模序列中频繁进行子序列求和操作的问题。传统方法的时间复杂度为O(n*m),而树状数组能将最坏情况下的时间复杂度降低到O(m*logn)。文中给出了C语言的实现示例,展示了如何进行插入、查询和更新操作,特别适合于需要高效处理连续子序列和的情况。
摘要由CSDN通过智能技术生成

在CF上做题时,碰到”Time limit exceeded”错误,程序中频繁的遍历连续子序列,当序列长度增加时,程序效率急剧下降,在此学习一种高效的数据结构——树状数组。

树状数组是一种数据结构,适合解决如下问题:

定义问题如下:我们有n个盒子,可能的操作为:

往第i个盒子增加石子

计算第k个盒子到第l个盒子的石子数量(包含第k个和第l个)

原始的解决方案中(即用普通的数组进行存储,box[i]存储第i个盒子装的石子数), 操作1和操作2的时间复杂度分别是O(1)和O(n)。假如我们进行m次操作,最坏情况下, 即全为第2种操作,时间复杂度为O(n*m)。使用数状数组,它在最坏情况下的时间复杂度也为O(m log n)。

C语言实现

#include

#define N 100

int a[N], c[N];

int LowBit(int x)

{

return x & (-x);

}

//求树状数组c

void GetArrayC()

{

int i, j;

for(i=0; i

{

c[i]=0;

for(j = i-LowBit(i)+1; j<=i; j++)

c[i] += a[j];

}

}

//数组a前n项和

int Sum(int n)

{

int sum=0;

while(n>0)

{

sum += c[n];

n=n - LowBit(n);

}

return sum;

}

//对c[i]增加x

void Change(int i, int x)

{

while(i<=N)

{

c[i] = c[i] + x;

i = i + LowBit(i);

}

}

//test

int main()

{

int i;

for(i=0; i

a[i] = i;

GetArrayC();

//求51+52+...+99的值

printf("%d\n", Sum(99)-Sum(50));

return 0;

}

特别是当求连续子序列和比较频繁时,该数据结构特别有效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值