1.题目
2.求解
这道题看通过率,一半,也说明了应该也是道简单题,很简单的线段树,甚至感觉用线段树都有些奢侈,因为这道题没有用到区域修改(个人认为这才是线段树的精髓)。除此之外区域求和也是线段树的一个特点,因此也是很容易想到要用线段树求解。(我虽然想到了 但是太久没做线段树的题目了导致我忘了流程是啥样的)
那么说啥都没有直接上代码来的直接,冲冲冲!
3.代码
class NumArray {
public:
int Sum[30005 << 2];
int len ;
void PushUp(int rt){
Sum[rt] = Sum[rt<<1] + Sum[rt<<1|1];
}
void Build(int l, int r, int rt, vector<int>& nums){
if(l == r){
Sum[rt] = nums[l];
return ;
}
int m=(l+r)>>1;
Build(l,m,rt<<1, nums);
Build(m+1,r,rt<<1|1, nums);
PushUp(rt);
}
//建树一定要注意虽然给的vector下标从0 - len-1但是创建的线段树一定要从1开始
//因为用到了位运算向左推一位的时候如果为0的情况推完还是0会覆盖之前的数据 千万注意!!!
void Update(int index, int val, int l, int r, int rt){
if(l == r){
Sum[rt] = val;
return ;
}
int m = (l + r) >> 1;
if(index <= m) Update(index, val, l, m, rt << 1);
if(index > m) Update(index, val, m + 1, r, rt << 1|1);
PushUp(rt);
}
int Query(int L, int R, int l, int r, int rt){
if(L <= l && r <= R) return Sum[rt];
int m = (l + r) >> 1;
// PushDown(rt, m - l + 1, r - m);
int ans = 0;
if(L <= m) ans += Query(L, R, l, m, rt << 1);
if(R > m) ans += Query(L, R, m+1, r, rt<<1|1);
return ans;
}
NumArray(vector<int>& nums) {
len = nums.size();
Build(0, nums.size() - 1, 1, nums);
PushUp(0);
}
void update(int index, int val) {
Update(index, val, 0, len - 1, 1);
}
int sumRange(int left, int right) {
return Query(left, right, 0, len - 1, 1);
}
};
/**
* 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);
*/
我的代码部分可能有些复杂,因为太久没写了大家酌情看 别骂我菜:)