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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基础树状数组

發布時間:2025/3/16 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基础树状数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如果給定一個數組,要你求里面所有數的和,一般都會想到累加。但是當那個數組很大的時候,累加就顯得太耗時了,時間復雜度為O(n),并且采用累加 的方法還有一個局限,那就是,當修改掉數組中的元素后,仍然要你求數組中某段元素的和,就顯得麻煩了。樹狀數組是一個查詢和修改復雜度都為log(n)的數據結構。主要用于查詢任意兩位之間的所有元素之和,但是每次只能修改一個元素的值;經過簡單修改可以在log(n)的復雜度下進行范圍修改,但是這時只能查詢其中一個元素的值。

基本概念:

假設數組a[1..n],那么查詢a[1]+...+a[n]的時間是log級別的,而且是一個在線的數據結構,支持隨時修改某個元素的值,復雜度也為log級別。


如圖所示,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的二進制從右往左數0連續的個數。

計算2^k用下面的方法:

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

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

x+=x&(-x)可以找到他的上一個節點,例如x=4,得到8;

x-=x&(-x)就是可以得到x所管轄的下個節點,例如x=7,然后得6,一直循環到x為0,就可以得到7所管轄的區域為1,2,3,4,5,6,7;

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

上面函數是修改的,因為樹狀數組是有管轄區域的,所以只要改一個點,那么它所管轄的店都要修改;

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

上面是求和函數;


例如:求1到7的和,代入Sum函數,循環一次走到6,再循環一次走到4,然后就循環結束了;

這是樹狀 數組的基本應用;

大神講解:

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。