樹狀數組

參考鏈接爲:

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) 的複雜度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章