演算法理解-樹狀數組

來源:互聯網
上載者:User

       樹狀數組是一種常見的計算最佳化方法,複雜度一般為nlog(n),有著非常強大的功能,如統計首碼和,部分和,逆序對,dp最佳化等都可以解決,有人常說它是線段樹的簡化版,但是它也有一定的局限性,對於很多區間更新統計的問題,樹狀數組往往有心無力,鑒於大部分資料都以樹的形式來講解,剛開始我也是這樣入門的,現在重新看一遍,發現有了更加深刻的理解,同時也感慨位元運算的神奇以及對發明樹狀數組那個人的無比敬仰。


        樹狀數組,顧名思義它是一個數組,儲存形式是樹狀的,很容易想到《資料結構》裡的二叉樹,但是這裡並不是二叉樹,確切的說,應該是多叉樹,想看的可以去百度百科看看,那裡有配圖。


        樹狀數組的巧妙所在,它利用了數位統計的分段統計的方法,結合二進位的表示方法,構造出了一顆樹,一顆沒有邊的樹。理解數狀數組我覺得要從它的分段方法,和二進位標記法出發講解。


      先看個例子:

      數組 a1=2,a2=1,a3=4,a4=2,a5=5,a6=3,a7=6,a8=4,a9=1,a10=2,a11=4,a12=7,a13=9,a14=8,a15=5,a16=6

      1111(b)這是15的二進位表示,假設我們要統計元素1~15的總和,那麼我們可以分為4段統計,0001~1000(1~8),1001~1100(9~12),1101~1110(13~14),1111~1111(15~15),可以看出分段的方法,以2^k這樣長度為一段,4段分別對應2^3,2^2,2^1,2^0.


       講完分段後,我們來看看樹狀數組的表示方法,樹狀數組裡面放的究竟是什麼呢?我們設樹狀數組為c[size],那麼

c[i]表示什麼呢,再舉個例子,我們要統計前10個元素的總和,我們令c[10]=c[1010(b)]=a[1001(b)]+a[1010(b)];也就是表示以最後一位1的位置劃分出來的段長,這裡最後一位1在第2位,那麼就是2^1長度,表示從第i個數到前2^k(即i的位元最後一位1表示的位權)個數的總和,這和我們上面例子講的分段方法完全相同,c[1010]可以這樣理解,元素號前兩位為10且<=1010的元素的總和,也就是2^1長度元素的總和,是不是有種數位統計的感覺,其實差不多,只是,樹狀數組可以修改調整,簡單的來說,樹狀數組是動態,數位統計是靜態,樹狀數組巧妙的設計,使得二進位可以表示一顆多叉樹上所有的聯絡。


       那麼我們統計c[10]=c[1010]的時候,我們就可以先統計c[1010]的值,即a[1010]+a[1001];然後我們就可以減掉這兩個數,即變成統計前8個元素的總和,c[8]=c[1000]=a[0001]+a[0010]+.....+a[1000]=sum[8],顯然可以發現c[2^k]表示的就是1~2^k總和。那麼前10個元素的總和就是sum = c[10] + c[8];


       以2^k為分段長度,以及樹狀數組c的含義知道後,可以知道,要統計前n項和,我們必須把n分成多個2^k段,長度不可能相同,統計的時候只要統計它包含的所有長度段就可以知道要加上哪些樹狀數組元素,這裡的段長表示就是n二進位時最後一位1的位權,所以只要從最後找到1的位置就ok了。


       那麼我們怎麼樣找到最後一位呢?前人已經為我們開路了,找x的最後一位1的位權lowbit=x&(-x)。

       這裡我們只講了怎麼樣統計,卻沒有講怎麼樣插入,有了統計的鋪墊,尋找就變的簡單了,顯然只要包含插入元素的樹狀數組才需要改變,假設我們要插入a[i],那麼哪些數組包含a[i]呢?a[i]至少包含在一個段長中,只要找到這個最短段長即可,顯然包含在最小那個段長中,那麼我們也只需要找到最後一個1的位權即可,那麼下一個要更新的就是x=i+lowbit(i)元素了,x更新了,那麼包含x的也應該要更新,y=x+lowbit(x);這樣一直下去直到超過最大的元素標號為止。

具體實現代碼如下

  

int lowbit(int n){return n&(-n);}int sum(int n) {int ans=0;while(n){ans+=c[n];n-=lowbit(n);}return ans;}void up(int n,int k){int i;for(i=n;i<=tem;i+=lowbit(i)){c[i]+=k;}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.