/*
* @lc app=leetcode id=307 lang=cpp
*
* [307] Range Sum Query - Mutable
*
* https://leetcode.com/problems/range-sum-query-mutable/description/
*
* algorithms
* Medium (29.96%)
* Likes: 804
* Dislikes: 66
* Total Accepted: 79.7K
* Total Submissions: 264.7K
* Testcase Example: '["NumArray","sumRange","update","sumRange"]\n[[[1,3,5]],[0,2],[1,2],[0,2]]'
*
* Given an integer array nums, find the sum of the elements between indices i
* and j (i ≤ j), inclusive.
*
* The update(i, val) function modifies nums by updating the element at index i
* to val.
*
* Example:
*
*
* Given nums = [1, 3, 5]
*
* sumRange(0, 2) -> 9
* update(1, 2)
* sumRange(0, 2) -> 8
*
*
* Note:
*
*
* The array is only modifiable by the update function.
* You may assume the number of calls to update and sumRange function is
* distributed evenly.
*
*
*/
class NumArray {
private:
vector<int> nodes;
int N;
public:
NumArray(vector<int>& nums) {
N = nums.size();
nodes.resize(2 * N);
// nums作为叶子
for (int i = N; i < 2 * N; ++i) {
nodes[i] = nums[i - N];
}
for (int i = N - 1; i >= 0; --i) {
nodes[i] = nodes[i * 2] + nodes[i * 2 + 1];
}
}
void update(int i, int val) {
nodes[i += N] = val;
while (i > 0) {
nodes[i / 2] = nodes[i] + nodes[i ^ 1];
i /= 2;
}
}
int sumRange(int i, int j) {
int sum = 0;
for (i += N, j += N; i <= j; i /= 2, j /= 2) {
// 左边界为右结点, 加上自己,并把范围缩小1。
if ((i & 1) == 1) sum += nodes[i++];
// 右边界为左结点, 加上自己,并把范围缩小1。
if ((j & 1) == 0) sum += nodes[j--];
}
return sum;
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* obj->update(i,val);
* int param_2 = obj->sumRange(i,j);
*/