树状数组适用范围:单点修改,区间修改,单点查询,区间查询

注:
a[]:原数组
tree[]:前缀和数组

-lowbit

int lowbit(int n)
{
    return n&(-n);
}:

-单点修改:

void add(int x,int k)//在a[x]加上k,相当于在tree[]中x~n区间加上k
{
    while(x<=N)
    {
        tree[x]+=k;
        x+=lowbit(x);
    }
}

-区间修改:

注意:要用到差分数组,与原来的前缀和数组不一样

void add_part(int x,int y,int k)//在a[x]~a[y]加上k,相当于在tree[]中x~y区间加上k,操作为从x~n区间加上k,再从y+1~n区间加上-k
{
    add(x,k);
    add(y+1,-k);
} 

- 单点查询:

int search(int x) //查询a[x]的值 
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}

- 区间查询:

int sum(int x,int y)//查询a[x]~a[y]的和,相当于c[y]-c[x-1]
{
    return search(y)-search(x-1);
}