给定一个整数数组 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 函数的调用次数是均匀分布的。
线段树的知识点可以参考:https://blog.csdn.net/zearot/article/details/48299459
递归写法:
class NumArray {
public:
vector<int> tree;
int len;
NumArray(vector<int>& nums)
{
len=nums.size();
tree=vector<int>(len<<2,0);
if(len==0)
return ;
build(1,len,1,nums);
}
void pushup(int point)
{
tree[point]=tree[point*2]+tree[point*2+1];
}
void build(int start,int end,int point,vector<int>& nums)
{
if(start==end)
{
tree[point]=nums[start-1];
return ;
}
int mid=start+(end-start)/2;
build(start,mid,point*2,nums);
build(mid+1,end,point*2+1,nums);
pushup(point);
}
int query(int L,int R,int l,int r,int p)//L,R表示操作区间,l,r表示当前tree节点区间,rt表示当前tree节点编号
{
if(L<=l&&R>=r)//这里要取小于大于是因为要保证非2^n情况成立,只需要包括区间就可以
{
return tree[p];
}
int res=0;
int mid=l+(r-l)/2;
if(L<=mid)
res+=query(L,R,l,mid,p*2);
if(R>=mid+1)
res+=query(L,R,mid+1,r,p*2+1);
return res;
}
void update(int point ,int val,int L,int R,int p)
{
if(L==R)
{
tree[p]=val;
return ;
}
int mid=L+(R-L)/2;
if(point<=mid)
update(point,val,L,mid,p*2);
else
update(point,val,mid+1,R,p*2+1);
pushup(p);
}
void update(int i, int val)
{
update(i+1,val,1,len,1);
}
int sumRange(int i, int j)
{
return query(i+1,j+1,1,len,1);
}
};
/**
* 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);
*/
非递归写法: