个人对lowbit() 的理解,
int lowbit(x){return x&(-x);}
n 补码是 ~ n ,~n+1=-n,所以写x&(-x)而不是x&(-x+1)
两个应用:首先是区间查询,g以上图的 节点6 为例(图源b站),6-lowbit(6)=4,4-lowbit(4)=0,t [ 6 ] 表示的是 a [ 5 ] ~ a [ 6 ] 的和,t [ 4 ] 表示的是 a [ 1 ] ~ a [ 4 ] 的和,因此t [ 6 ] + t [ 4 ] 得到是 a [ 1 ] ~ a [ 6 ] 和,getsum( i ) 又称ask( i ) 得到的就是前 i 个和;其次是单点增减,以上图的 节点4 为例,6+lowbit(6)=8,t [ 4 ] 表示的是 a [ 1 ] ~ a [ 4 ] 的和,t [ 2 ] 表示的是 a [ 1 ] ~ a [ 2 ] 的和,t [ 3 ] 表示的是 a [ 3 ] 的和,改变的是 a [ 4 ],不影响t [ 2 ] 和t [ 3 ] , 因此只改变 t [ 4 ] 及其父节点,增加 add( x , k ),减少 add( x , -k )
然后是今天做题中发现的问题,对于定义的树状数组 t [ x ] ,在初次输入时,必须写add(i,a)对树状数组维护,切记不能写scanf("%d",&t[i]),因为 t [ x ] 表示的是包括 a [ x ] 以及t [ x ] 的子节点之和,scanf输入只算了a [ x ] 而没算t [ x ] 的子节点