• 树状数组知识入门


    树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改。
    如百度上所讲 :在解题过程中,我们有时需要维护一个数组的前缀和 S[i]=A[1]+A[2]+…+A[i]。但是不难发现,如果我们修改了任意一个 A[i],S[i]、 S[i+1]…S[n]都会发生变化。可以说,每次修改 A[i]后,调整前缀和 S 在最坏情况下会需要 O(n)的时间。当 n 非常大时,程序会运行得非常缓慢。因此,这里我们引入“树状数组”,它的修改与求和都是 O(logn)的,效率非常高。
    具体如下图
    这里写图片描述
    令这棵树的结点编号为C1,C2…Cn。令每个结点的值为这棵树的值的总和,那么容易发现:
    C1 = A1
    C2 = A1 + A2
    C3 = A3
    C4 = A1 + A2 + A3 + A4
    C5 = A5
    C6 = A5 + A6
    C7 = A7
    C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8

    C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16
    这个规律是怎么实现的呢?

    这里有一个有趣的性质:
    设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax,
    所以很明显:Cn = A(n – 2^k + 1) + … + An

    用最小幂 2^k建立树状数组c、并且能进行更新元素值、子序列求和等。对于这个最小幂 2^k(k为x二进制末尾0的个数)
    算这个2^k有一个快捷的办法,定义一个函数如下即可:
    int lowerbit(int x)
    {
    return x&(x^(x–1));
    }

    利用机器补码特性,也可以写成:
    int lowerbit(int x)
    {
    return x&-x;
    }

    对树的维护代码,也就是对原有数据进行修改

    void add(int k,int num)  //从k改变 k后存储的数组的和也要改变
    {  
           while(k<=n)  
            {  
                tree[k]+=num;  
                k+=lowbit(k);  
            }  
    }

    有了上面的基础,求和就比较简单了。比如求0001~0110的和就直接c[0100]+c[0110],分析方法与上面的恰好逆过来,而且写法也是逆过来的:

    int read(int k)//1~k的区间和  
    {  
           int sum=0;  
            while(k)  
            {  
                sum+=tree[k];  
                k-=k&-k;  
            }  
            return sum;  
    }

    数组和的初始计算,通过lowbit计算出树状数值。

    void initsum()
    {
        for(int i=n;i>=1;i--)
        {
            int num=0;
            for(int j=i-lowbit(i)+1;j<=i;j++)
                num+=t[j];
            t[i]=num;
        }
    }
  • 相关阅读:
    还在使用golang 的map 做Json编码么?
    Golang 性能测试(2) 性能分析
    golang 性能测试 (1) 基准性能测试
    消息队列 NSQ 源码学习笔记 (五)
    消息队列 NSQ 源码学习笔记 (四)
    消息队列 NSQ 源码学习笔记 (三)
    消息队列 NSQ 源码学习笔记 (二)
    消息队列 NSQ 源码学习笔记 (一)
    你不知道的空格
    Supervisor 使用和进阶4 (Event 的使用)
  • 原文地址:https://www.cnblogs.com/nanfenggu/p/7900100.html
Copyright © 2020-2023  润新知