BIT树
BIT树,也称树状数组,是能够完成下述操作的数据结构:
给一个初始值全为零的数列,a1,a2……an
(1) 给定i,计算a1+a2+……ai
(2) 给定i和x,执行ai+=x
算出对应编码最低位第一个非零值的权值的为公式:i&(-i),原理:
基于补码,因为负数的补码就是最高位填写符号位后除符号位所有位都按位取反再加一,那么此时,最低位第一个非零元素的右边原本肯定都是零,取反后就都是一,再加一就会不断进位直至取反后第一个为0的地方停止进位,那这个位置也就是原本最低位第一个为1的位置,这时候它就会因为前面的进位变为1,那么此时观察-i与原i的二进制的区别,原本i第一个为1的地方-i用补码表示还是1,而这个位置的前面因为按位取反了,他们两个相与肯定都是0,这个位置的后面原本的i都是0,-i因为进位的缘故也都是0,所以也还是0,也就是相与过后的数字就是原本的i的最低为的第一个非零为对应的权值了。
#include<iostream>
#include<cstdio>
#define MAX_N 10000
using namespace std;
int bit[MAX_N+1],N;
void add_bit(int i,int x)// 给定i和x,执行ai+=x
{
while(i<=N)
{
bit[i]+=x;//基于补码,可以算出最低非零位对应的权值
i+=i&(-i);
}
}
int sum(int i)//计算1至ai的和
{
int sum=0;
while(i)
{
sum+=bit[i];
i-=i&(-i);
}
return sum;
}
int main()
{
int num;
cin>>N;
for(int i=1;i<=N;++i)
{
cin>>num;
add_bit(i,num);
}
}