树状数组学习笔记
位运算是补码进行运算的
因此可以解释负数进行位运算时的奇妙现象
- 补码:正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
E:原码:10000001;
补码:01111111.
- lowbit:lowbit这个函数的功能就是求某一个数的二进制表示中最低的一位1
E:lowbit(10001)=1,lowbit(10010)=10。 - lowbit的实现方式:
int lowbit(x)
{
return x - (x & (x - 1));
}
2.(推荐)
int lowbit(x)
{
return x & -x;
}
E:lowbit(1000011)=1000111&(0111001)=1;
lowbit(100100)=100100&(011100)=100.
- 树状数组:
- add操作
void add(int i,int k){
while(i<=n){
c[i]+=k;
i+=lowbit(i);
}
}
在从 \(C_i\) 到受 \(C_i\) 影响的所有\(C\)数组中的数+=k;
- 查询操作
int ask(int i){
int ans=0;
while(i){
ans+=c[i];
i-=lowbit(i);
}
return ans;
}
求 \(C_1\) 到 \(C_i\) 的前缀和。
\(C\) 数组中存的是原数组的差分或原数,就可以支持区间/单点的查询/修改。
配图使用更佳。