树状数组

本文介绍了一种高效的数组结构——树状数组(Binary Indexed Tree),它主要用于快速获取数组中连续n个数的和,并且能够应对频繁的元素修改。文章详细阐述了树状数组的基本概念、实现原理及操作方法,包括如何通过树状数组实现单点更新和区间求和等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树状数组(binary indexed tree)
概念:是一种数组结构
目的:高效地获取数组中连续n个数的和。
应用 :序列中的元素可不断地被修改,要快速地获取某区间和(单点更新,区间求和)
前注 :如果每次要修改的不是单个元素,而是一个区间,那不应当用树状数组(效率过低)

操作:
1.修改元素(增减值) –> O(logn)
2.求区间和 –> O(logn)

实现:
给定序列(数列)A,我们设一个数组C满足

C[i] = A[i–2^k+ 1] + … + A[i]
        (K为 i在二进制下末尾0的个数, i >= 1)  --> 给定 i,则有 2^k = i&(i^(i-1)) = i&(-i)

图示:
这里写图片描述

修改元素:
————–>若要修改A[i]的值时,只需从C[i]往根节点一路上溯,调整这条路上的所有C[]。
区间求和:
————–>求数列的前n项和,只需找到n以前的所有最大子树,把其根节点的C[]值加起来。(子树的数目是n在二进制时1的个数)

int lowbit(int n)
{//求 2^k , k 为n在二进制下末尾0的个数
    return n & (-n); // == n & (n^(n-1));
}
int Sum(int End)        
{//求前n项和
    int ans = 0;
    while(End > 0)
    {
        ans += treeC[End];
        End -= lowbit(End);
    }
    return ans;
}
void Plus(int pos,int num,int len) 
{//增加某元素的值
    while( pos <= len )
    {
        treeC[pos] += num;
        pos += lowbit(pos);
    }
}

例题 http://acm.hdu.edu.cn/showproblem.php?pid=1166


高级应用 : 区间更新 单点查找

操作:
1.区间更新
例如 :
在 区间[ Begin,End] 加 Add

则Plus(Begin,Add)   Plus(End+1,-Add)

实现了更新区间[ Begin,End] 的值而不改变其他值

2.单点查找

Sum(i) 即为 A[i] 的值

例题 http://acm.hdu.edu.cn/showproblem.php?pid=1556


推广 : 二维树状数组
用途 :
一个由数字构成的大矩阵,能进行
操作
1) 修改矩阵元素(增减值)
2) 求子矩阵的和

求和有
有 C[x][y] = sum{ A[i][j] , x - lowbit[x] +1 <=i <= x , y-lowbit[y]+1 <= j <=y }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值