【算法】树状数组

更好的观看 :链接
树状数组和线段树的区别:
区别
  • 线段树可解决的题目多

  • 树状数组代码短,常数很小

[]
[
]

树状数组

1. 特点:可以动态、快速地求前缀和。
2. 时间复杂度:O(log n)。
3. 原理

树状数组是1维表示(为了清楚,才划分的层次)
image

c[1] = a[1]
c[2] = c[1] + a[2] = a[1] + a[2]
c[3] = a[3]
c[4] = c[2] + c[3] + a[4] = a[1] + ... + a[4]
c[5] = a[5]
c[6] = c[5] + a[6] = a[5] + a[6]
c[7] = a[7]
c[8] = c[4] + c[6] + c[7] + a[8] = a[1] + ... + a[8]
c[9] = a[9]
c[10] = c[9] + a[10] = a[9] + a[10]
c[11] = a[11]
c[12] = c[10] + c[11] + a[12] = a[9] + ... + a[12]
c[13] = a[13]
c[14] = c[13] + a[14] = a[13] + a[14]
c[15] = a[15]
c[16] = c[8] + c[12] + c[14] + c[15] + a[16] = a[1] + ... + a[16]
......
4. 核心公式

c[x] = a[x-2^k] + ... + a[x] = a[x-lowbit(x)] + ... + a[x]
x的二进制表示最后k个0
lowbit(x) = x & -x , 表示一个数的二进制最低位的1在从右往左数的位置

5. 可解决的问题:
  • ① 给某个位置上的数加上一个数**(单点修改)** O(log n)

    • 给某个位置上的数加一个数的代码:使a[x] + v
    for(int i = x;i <= n;i += lowbit(i))
    	c[i] += v;
    
  • ② 求某一个前缀和**(区间查询)** O(log n)

    • c[x] + c[x-lowbit(x)] + ...
    • 求和代码(递归)
    int res = 0;
    for(int i = x;i > 0;i -= lowbit(i))
    	res += c[i];
    return res;
    
6.模板题

AcWing 1264. 动态求连续区间和

7.树状数组的三个核心函数
int lowbit(int x)
{
    return x & -x;
}

void add(int x,int v)
{
    for(int i = x;i <= n;i += lowbit(i))
        c[i] += v;
}

int query(int x)
{
    int res = 0;
    
    for(int i = x; i ;i -= lowbit(i))
        res += c[i];
    
    return res;
}
8.例题

AcWing 1265. 数星星
AcWing 1270. 数列区间最大值


很抱歉,根据提供的引用内容,没有找到关于迪杰斯特拉算法树状数组优化的信息。但是,我可以为您介绍一下迪杰斯特拉算法树状数组的基本概念和应。 迪杰斯特拉算法,也称为狄克斯特拉算法,是一种用于解决图中最短路径问题的算法。该算法的基本思想是从起点开始,逐扩展到距离起点更远的节点,直到到达终点为止。在扩展的过程中,通过比较不同路径的距离,选择距离最短的路径进行扩展,直到到达终点。 树状数组,也称为二叉索引树,是一种用于高效维护序列前缀和的数据结构。该数据结构可以在O(log n)的时间内完成单点修改和区间查询操作,因此被广泛应用于解决各种算法问题,如逆序对问题、区间最大值/最小值问题等。 虽然迪杰斯特拉算法树状数组看似没有直接关系,但是在解决某些特定的问题时,两者可以结合使用,以达到更高效的解决方案。例如,在解决带权图最短路径问题时,可以使用迪杰斯特拉算法结合树状数组进行优化,以达到更快的计算速度。 具体来说,可以使用树状数组维护一个优先队列,用于存储当前已经扩展的节点和它们的距离。在每次扩展节点时,可以使用树状数组快速找到距离最小的节点,并将其从队列中删除。这样可以避免使用传统的堆数据结构,从而提高算法的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值