树状数组和线段树的理解

-----感谢SDU-ACM的教程分享,具体教程可在B站上搜索
树状数组总结:
    1、思想:按照2的整数次幂进行分解,把一个前缀区间分解成若干个长度为2的整数次幂的小区间。例如[1,6]分解为6=4+2,即:
    [1,4]和[5,6]
    2、lowbt(x)函数:获取整数x的2的整数次幂的拆分中,最小的那个2次幂(也即:1中所说的拆分中区间长度最短的那个区间的长度)
    3、树状数组的定义:
        1)令 第x记录(x - low_bit x),x]中的数字之和为tree[x],其中(x - low_bit(x),x]是一个左闭右开的区间
        2)令第x个位置的父节点为 x+low_bit(x)
    4、性质:
        1)一个节点i,记录区间(i-low_bit(i),i]的区间信息,其子节点记录的区间不会相互覆盖,且按照从小到大
        依次覆盖区间(i-low_bit(i),i]
        2)一个节点i仅会被节点i及其祖先节点所覆盖

类比线段树总结:
    线段树主要是用于维护一个区间的信息。其思想是:按照区间长度进行对半分,左右子树仍然是递归维护一个
    区间的信息,只不过左子树维护的是父节点的前半部分的信息,右子树维护的是父节点后半部分的信息。

//树状数组模板

static int n;  // n 为树状数组中的元素个数
static int tree[(int )1e5];

static int low_bit(int x)
{
    return (x & (-x) );
}

static void Update( int x, int change)  //树状数组的更新函数
{
    while (x <= n )
    {
        tree[x] += change;
        x += low_bit(x);
    }
}

static int Sum(int x)  //树状数组的求和函数
{
    int sum = 0;
    while (x > 0)
    {
        sum += tree[x];
        x -= low_bit(x);
    }
    return sum;
}

 

你可能感兴趣的:(数据结构与算法)