[算法]树状数组

树状数组

树状数组怎么来滴

所有的整数都可以表示成2的幂和,我们也可以把一串序列表示成一系列子序列的和。采用这个想法,我们可将一个前缀和划分成多个子序列的和,而划分的方法与数的2的幂和具有极其相似的方式。
一方面,子序列的个数是其二进制表示中1的个数,
另一方面,子序列代表的f[i]的个数也是2的幂

树状数组用在什么地方呢

常用于区间和查询、单点修改

树状数组的模板
class NumArray {
    vector<int> tree;
	vector<int>& arr;
	int n;
	int lowbit(int x) {
		return x & -x;
	}
	//求前缀和
	int quary(int x) {
		int ans = 0;
		for (int i = x; i > 0; i -= lowbit(i)) {
			ans += tree[i];
		}
		return ans;
	}
	//x位置更新num
	void add(int x, int num) {
		for (int i = x; i <= n; i += lowbit(i)) {
			tree[i] += num;
		}
	}
public:
	NumArray(vector<int>& nums) :tree(nums.size() + 1), arr(nums) {
		n = nums.size();
                //初始化树状数组
		for (auto i = 0; i < n; i++) {
			add(i + 1, nums[i]);
		}
	}
	void update(int index, int val) {
		add(index + 1, val - arr[index]);
		arr[index] = val;
	}
	int sumRange(int left, int right) {
		return quary(right + 1) - quary(left);
	}
};
复杂度分析

时间复杂度 O(logn)
空间复杂度 O(n)

posted @ 2022-04-04 15:21  Excting  阅读(19)  评论(0编辑  收藏  举报