树状数组适用范围:单点修改,区间修改,单点查询,区间查询
注:
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);
}