參考鏈接爲:
https://blog.csdn.net/Small_Orange_glory/article/details/81290634
https://blog.csdn.net/int64Ago/article/details/7429868
C[i]代表子樹的葉子節點的權值之和
C[1]=A[1]
C[2]=A[1]+A[2]
C[3]=A[3]
C[4]=A[1]+A[2]+A[3]+A[4]
……
將節點序號轉化爲二進制,發現
C[i]=A[i-2^k+1]+A[i-2^k+2]+……+A[i] (k爲i的二進制的末尾0的個數)
引入lowbit( x ) 取出x的最低位1,也就是說lowbit(x)=2^k
int lowbit(int t){
return t&(-t);
}
在上面運算的過程中是用帶符號的二進制數計算的,其中 - 表示求反碼
那麼 C[i] = A[i-lowbit(i)+1]+A[i-lowbit(i)+2]+.......+A[i]
另一種說法是C[0110]代表着從0110開始計算0010個數的和
樹狀數組有兩個代碼公式,一個是區間查詢,也就是求A數組中前i項的和
按照參考網址給出的示例,得到對應的代碼 getsum(x)
int getsum(int pos){
int ans=0;
while(pos){
ans+=C[pos];
pos-=lowbit(pos);
}
return ans;
}
另一個爲單點更新,數組A更新時如何更新數組C呢
void update(int pos,int delta){
while(pos<=n){
C[pos]+=delta;
pos+=lowbit(pos);
}
}
數組維護和查詢都是O(logn) 的複雜度。