给你一个数组 nums ,请你完成两类查询,其中一类查询要求更新数组下标对应的值,另一类查询要求返回数组中某个范围内元素的总和。
实现 NumArray 类:
NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值更新为 val
int sumRange(int left, int right) 返回子数组 nums[left, right] 的总和(即,nums[left] + nums[left + 1], …, nums[right])
/*
range sum query
*/
/*
使用树状数
*/
// 定义 树状数的一个类
class FenwickTree
{
public:
FenwickTree(int n): sums_(n + 1, 0) {}
void update(int i, int val)
{
while (i < sums_.size())
{
sums_[i] += val;
i += lowbit(i);
}
}
int query(int i) const
{
int sum = 0;
while (i > 0)
{
sum += sums_[i];
i -= lowbit(i);
}
return sum;
}
private:
vector<int> sums_;
// 设置成 静态 的 内联 函数
static inline int lowbit(int x)
{
return x & (-x);
}
};
class NumArray {
public:
// 构造函数的 初值列
NumArray(vector<int>& nums): nums_(std::move(nums)), tree_(nums_.size())
{
// nums_ = nums;
// tree_(nums.size());
// 直接调用 update 来更新节点元素,并更新树节点,时间复杂度是 i+logi i属于[0, nums.size(0))
for (int i = 0; i < nums_.size(); ++i)
{
// 树状数组的下标是从1开始的,所以是 i+1
tree_.update(i + 1, nums_[i]);
}
}
// mutable 可变的,所以提供一个接口可以改变数组的某个值,但是改变之后,update tree 也要相应的更新
// 这里更新两个,一个是更新 update tree,一个是更新 nums_ 数组
void update(int index, int val) {
// 这里只需要更新 val与nums_[index] 的差即可,也就是增量
tree_.update(index + 1, val - nums_[index]);
nums_[index] = val;
}
int sumRange(int left, int right) {
// 相当于是:求数组中 0-right 范围的和 减去 0-(left-1) 位置的和
// 因为树状数组的下标是从 1 开始的,所以就表示为下面这样的
return tree_.query(right + 1) - tree_.query(left);
}
private:
vector<int> nums_;
FenwickTree tree_;
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* obj->update(index,val);
* int param_2 = obj->sumRange(left,right);
*/