樹狀數組1
阿新 • • 發佈:2019-02-06
簡單 為什麽 時間復雜度 二進制 組的建立 void 問題 普通 class
今天花了半個下午的時間可算是把它給搞明白了。。。
什麽是樹狀數組呢?先來看一張圖(網上剪的。。。)
沒有看懂沒關系,看懂就怪了(滑稽)
樹狀數組可以做到每一次查詢時間復雜度為O(1),並且修改為O(logn),%%%
當看到logn時,難道不應該想到二進制嗎???
確實,樹狀數組和二進制有很大的關系,說實話,他和樹的關系不大(那他為什麽叫樹狀數組呢?好問題。。。)
簡單來說,每一個單元格所儲存的數據個數就是他在二進制下從右面往左數直到第一個1出現時,這個1右面的數。(怎樣,是不是特別的迷。。。)
舉個例子:2(10)存儲的個數就是10也就是2,8(1000)就是1000也就是8.
這下就應該明白了吧。
樹狀數組的建立和修改比較簡單,如果只是普通的存儲數據就只要在輸入時把涉及到的單元格都加上這個數就可以了,先上代碼:
1 void add(int x,int k) 2 { 3 while(x<=n) 4 { 5 tree[x]+=k; 6 x+=lowbit(x); 7 } 8 }
你可能會有一些疑問:lowbit是什麽呢?
lowbit就是求一個數在二進制下從右往左,直到第一個1出現時這一串數的值,所以我們不斷的加上lowbit就可以找到每個存儲數據的點了。(不懂的話就再看看圖吧。。。)
如果是求區間[x,y]和的話,我們只要求前y個數之和和前x-1個數之和,相減即可,而至於如何求前i個數之和,只要不斷減去lowbit即可(還是看圖理解吧。。。),附上代碼:
1 int sum(int x) 2 { 3 int ans=0; 4 while(x>0) 5 { 6 ans+=tree[x]; 7 x-=lowbit(x); 8 } 9 return ans; 10 }
關於區間修改和單點查詢,在下一篇博客會詳細的講解(我太懶了。。。)
樹狀數組1