树状数组
模板
int lowbit(int k) //求前驱和后继
{
return k&(-k);
}
void add(int k,int v)//在k上加v
{
while(k <= n)
{
c[k] += v;
k += lowbit(k);
}
}
int getsum(int k)//求1-k的前缀和
{
int res = 0;
while(k)
{
res += c[k];
k -= lowbit(k);
}
}
区间更新(建差分树)
例如对于下面这个数组
- A[] = 1 2 3 5 6 9
- D[] = 1 1 1 2 1 3
如果我们把[2,5]区间内值加上2,则变成了
- A[] = 1 4 5 7 8 9
- D[] = 1 3 1 2 1 1
//[x,y]区间内加上k
add(x,k); //A[x] - A[x-1]增加k
add(y+1,-k); //A[y+1] - A[y]减少k
a[n] = c[n];(单点查询)