给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2) sumRange(0, 2) -> 8
说明:
- 数组仅可以在 update 函数下进行修改。
- 你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。
一般写法
class NumArray
{
vector<int> nums;
vector<int> temp;
public:
NumArray(vector<int> nums)
{
this->nums = nums;
temp = nums;
int val = 0;
for (int i = 0; i < this->nums.size(); i++)
{
this->nums[i] = this->nums[i] + val;
val = this->nums[i];
}
}
void update(int i, int val)
{
int offset = val - temp[i];
temp[i] = val;
for (int j = i; j < this->nums.size(); j++)
{
nums[j] += offset;
}
}
int sumRange(int i, int j)
{
if(i == 0)
return nums[j];
else
{
return nums[j] - nums[i - 1];
}
}
};
线段树
class NumArray
{
struct SegNode
{
int val;
int addmark; //延迟更新
};
vector<SegNode> v;
int n;
public:
NumArray(vector<int> nums)
{
//
if(nums.size() <= 0)
return;
n = nums.size() - 1;
v = vector<SegNode>(nums.size() * 4 + 1);
buildTree(0, 0, n, nums);
}
~NumArray()
{
}
void buildTree(int root, int start, int end, vector<int> &nums)
{
if(start == end)
{
v[root].val = nums[start];
}
else
{
//*int mid = (start + end) / 2;
int mid = start + (end - start) / 2;
buildTree((root << 1) + 1, start, mid, nums);
buildTree((root << 1) + 2, mid + 1, end, nums);
v[root].val = v[(root << 1) + 1].val + v[(root << 1) + 2].val;
}
}
void updateTree(int root, int start, int end, int index, int newVal)
{
if(start >= end)
{
if(index == start)
{
v[root].val = newVal;
}
return;
}
int mid = start + (end - start) / 2;
if(index <= mid)
updateTree((root << 1) + 1, start, mid, index, newVal);
else
updateTree((root << 1) + 2, mid + 1, end, index, newVal);
v[root].val = v[(root << 1) + 1].val + v[(root << 1) + 2].val;
}
int queryTree(int root, int start, int end, int qstart, int qend)
{
if(start > qend || end < qstart)
{
return 0;
}
if(start >= qstart && end <= qend)
{
return v[root].val;
}
int mid = start + (end - start) / 2;
if(qstart >= mid + 1)
{
return queryTree((root << 1) + 2, mid + 1, end, qstart, qend);
}
else if(qend <= mid)
{
return queryTree((root << 1) + 1, start, mid, qstart, qend);
}
else
{
int ans1 = queryTree((root << 1) + 1, start, mid, qstart, qend);
int ans2 = queryTree((root << 1) + 2, mid + 1, end, qstart, qend);
return ans1 + ans2;
}
}
void update(int i, int val)
{
updateTree(0, 0, n, i, val);
}
int sumRange(int i, int j)
{
return queryTree(0, 0, n, i, j);
}
};
树状数组
class NumArray
{
public:
vector<int> nums;
vector<int> sums;
NumArray(vector<int> nums)
{
this->nums = nums;
sums.resize(nums.size() + 1);
sums[0] = 0;
for (int i = 0; i < nums.size(); i++)
{
change(i + 1, nums[i]);
}
/*for(auto a : sums)
{
cout << a << endl;
}*/
}
int lowbit(int x)
{
return x & (-x);
}
int sum(int n)
{
int val = 0;
while(n > 0)
{
val += sums[n];
n -= lowbit(n);
}
return val;
}
void change(int i, int val)
{
while(i < sums.size())
{
sums[i] += val;
i += lowbit(i);
}
}
void update(int i, int val)
{
int offset = val - nums[i];
nums[i] = val;
change(i + 1, offset);
}
int sumRange(int i, int j)
{
return sum(j + 1) - sum(i);
}
};