日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基础树状数组

發(fā)布時(shí)間:2025/3/16 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基础树状数组 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

如果給定一個(gè)數(shù)組,要你求里面所有數(shù)的和,一般都會(huì)想到累加。但是當(dāng)那個(gè)數(shù)組很大的時(shí)候,累加就顯得太耗時(shí)了,時(shí)間復(fù)雜度為O(n),并且采用累加 的方法還有一個(gè)局限,那就是,當(dāng)修改掉數(shù)組中的元素后,仍然要你求數(shù)組中某段元素的和,就顯得麻煩了。樹狀數(shù)組是一個(gè)查詢和修改復(fù)雜度都為log(n)的數(shù)據(jù)結(jié)構(gòu)。主要用于查詢?nèi)我鈨晌恢g的所有元素之和,但是每次只能修改一個(gè)元素的值;經(jīng)過簡(jiǎn)單修改可以在log(n)的復(fù)雜度下進(jìn)行范圍修改,但是這時(shí)只能查詢其中一個(gè)元素的值。

基本概念:

假設(shè)數(shù)組a[1..n],那么查詢a[1]+...+a[n]的時(shí)間是log級(jí)別的,而且是一個(gè)在線的數(shù)據(jù)結(jié)構(gòu),支持隨時(shí)修改某個(gè)元素的值,復(fù)雜度也為log級(jí)別。


如圖所示,c[1]=A[1],c[2]=A[1]+A[2],c[3]=A[3],c[4]=c[2]+c[3]+A[4]=A[1]+A[2]+A[3]+A[4]……;

c[n]=A[n – 2^k + 1]+..…+A[n];k為n的二進(jìn)制從右往左數(shù)0連續(xù)的個(gè)數(shù)。

計(jì)算2^k用下面的方法:

int lowbit(int x) {return x&(x^(x-1)); } 利用機(jī)器補(bǔ)碼特性,也可以寫成:

int lowbit(int x) {return x&(-x); } x&(-x)是個(gè)神奇的方法。

x+=x&(-x)可以找到他的上一個(gè)節(jié)點(diǎn),例如x=4,得到8;

x-=x&(-x)就是可以得到x所管轄的下個(gè)節(jié)點(diǎn),例如x=7,然后得6,一直循環(huán)到x為0,就可以得到7所管轄的區(qū)域?yàn)?,2,3,4,5,6,7;

void add(int i,int x) {while(i<=n){c[i]=c[i]+x;i+=loebit(i);} }

上面函數(shù)是修改的,因?yàn)闃錉顢?shù)組是有管轄區(qū)域的,所以只要改一個(gè)點(diǎn),那么它所管轄的店都要修改;

int Sum(int n) {sum=0;while(n>0){sum+=c[n];n-=loebit(n);} }

上面是求和函數(shù);


例如:求1到7的和,代入Sum函數(shù),循環(huán)一次走到6,再循環(huán)一次走到4,然后就循環(huán)結(jié)束了;

這是樹狀 數(shù)組的基本應(yīng)用;

大神講解:

http://blog.csdn.net/int64ago/article/details/7429868

http://www.cnblogs.com/zhangshu/archive/2011/08/16/2141396.html

http://blog.csdn.net/shahdza/article/details/6314818

總結(jié)

以上是生活随笔為你收集整理的基础树状数组的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。