树状数组(Binary Indexed Tree)

Binary Indexed Tree,从字面上来看是数,但是其实是数组。这个数组主要用来数组求和。例如对于某个数组[1,2,3,4,5],其树状数组的定义是:c[i]=a[i-2^r+1]+...+a[i],其中r是i二进制中最后一个1的长度。

2^r的确定是i & (i ^ (i - 1))。

树状数组主要有一下应用:求解树状数组,求前n项的和,当某个位置发生变化更新树状数组,获取某特定位置的值。

其代码如下:

#include <iostream>
#include <vector>
using namespace std;

int getIndex(int x) {
    return x & (x ^ (x - 1));
}
//构建树状数组
void buildTree(vector<int> &nums, vector<int> &tree){
    for(int i = 0;i < nums.size();i++) {
        int pos = i + 1;
        int index = getIndex(pos);
        for(int j = pos - index; j < pos;j++) {
            tree[i] += nums[j];
        }
    }
}
//求前n项的和
int getSum (vector<int> &trees, int pos) {
    int sum = 0;
    while(pos >= 0) {
        sum += trees[pos];
        pos -= (getIndex(pos + 1));
    }
    return sum;
}
//某个位置的数值发生变化,val是差值
void update(vector<int> &trees, int pos, int val) {
    while (pos < trees.size()) {
        trees[pos] += val;
        pos += getIndex(pos + 1);
    }
}
//获取特定位置的值
int getPosNum(vector<int> &trees, int pos) {
    if (pos == 0) {
        return trees[pos];
    }
    int sum = trees[pos];
    int z = pos - getIndex(pos + 1);
    pos -= 1;
    while (pos != z) {
        sum -= trees[pos];
        pos -= getIndex(pos + 1);
    }
    return sum;
}
int main(){
    int a[10] = {5,12,-3,13,4,1,5,9,2,7};
    vector<int> nums(a, a + 10);
    vector<int> tree(10, 0);
    buildTree(nums,tree);
//    int c = getSum(tree,3);
//    cout << c << endl;

//    update(tree,2,2);
//    for (int i = 0;i < 10;i++) {
//        cout << tree[i] << endl;
//    }

    int c = getPosNum(tree,2);
    cout << c << endl;
}


发布了115 篇原创文章 · 获赞 25 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/lion19930924/article/details/67642391
今日推荐