class NumArray {
public:
//树状数组模板题, 树状数组支持两种操作,一个给某一个数加上一个数,另一个是求区间前缀和
//要背过这个树状数组模板,注意树状数组下标必须从1开始
//树状数组三个函数,一个lowbit,一个add,一个sum
int n;
vector<int>tr,nums;
int lowbit(int x)
{
return x&-x;
}
int query(int x)
{
int res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
void add(int x,int v)
{
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=v;
}
NumArray(vector<int>& _nums) {
nums=_nums;
n=nums.size();
tr.resize(n+1); //树状数组下标必须从1开始
//初始化树状数组 o(n)时间复杂度
for(int i=1;i<=n;i++)
{
tr[i]=nums[i-1];
for(int j=i-1;j>i-lowbit(i);j-=lowbit(j))
{
tr[i]+=tr[j];
}
}
//for(int i=1;i<=n;i++) add(i,nums[i-1]); 另一种初始化方式
}
void update(int index, int val) {
add(index+1,val-nums[index]); //add是给某一下标加上一个数
nums[index]=val; //注意还要更新原数组
}
int sumRange(int left, int right) {
return query(right+1)-query(left); //query维护的是一个前缀和,所以这样求指定区间的前缀和
}
};
/**
* 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);
*/
力扣307 区域和探索 树状数组模板
最新推荐文章于 2024-10-01 05:04:32 发布