樹狀陣列篇:
首先我們來了解乙個應用:
我們需要求乙個陣列的前n項的和:
這麼簡單的問題我們不是可以這樣嗎?
for
(int i=
0;i)cout<
但是當我們需要控制時間複雜讀小於o(n),則我們需要怎麼辦呢?
這個時候我們就可以利用樹狀陣列了:
樹狀陣列的修改和控制的時間複雜度都是o(logn)
下面介紹什麼是樹狀陣列
c陣列就是樹狀陣列 a陣列是原陣列 c[i]是對應a陣列的樹狀陣列 當我們需要的時候就直接按照下表搜尋
我們建立乙個這樣的陣列的時間複雜度時o(nlogn)
由上圖可知
sum(i)就是陣列a的前i項的和
比如i=2
假如計算機的位數是16位的則i的二進位制是:
-i的二進位制是
則i&(-i)=2
= 0000000000000010=2
具體的去了解計算機的原碼、補碼、反碼的轉換方式現在就是上面的具體**怎麼實現:
在add函式中最重要便是:
如果a[i]在c中的某些項中則這些項需要加上a[i],因此每乙個a[i]中的項都需要進行
一項相同的操作:就是把這個a[i]加到含有它的c陣列中間去
所以就有:
#這裡使用的是python語言 如果沒有學過就當成偽**看即可
deflowbit
(x):
return x&
(-x)
defadd
(x,a,c)
: y=x
while x <
len(l)-1
: a[x]
+= c[y]
x+=lowbit(x)
在c陣列做好了那麼如何求前n項和呢?
我們要利用這條性質:
所以就有:
def
get_sum
(x,c)
sum=
0while x >0:
sum+= c[x]
x -= lowbit(x)
return
sum
整個完整的**如下
# this is tree array python source code
import numpy as np
deflowbit
(x):
return x&
(-x)
defadd
(x,p,l)
: y=x
while x <
len(l)-1
: p[x]
+= l[y]
x+=lowbit(x)
defbuild_tree_array
(l,p)
:for x in
range(1
,len
(l))
: add(x,p,l)
defget_sum
(x,l)
:sum=0
while x >0:
sum+= l[x]
x -= lowbit(x)
return
sumif __name__==
'__main__'
:#**從這裡開始執行
l=np.zeros(11,
int)
#l是原始的a陣列乙個一維陣列含由11個數
p=np.zeros(11,
int)
#p是c陣列初始化都為0
build_tree_array(l,p)
y=1for x in
input()
.split():
#這裡是輸入1 2 3 4 5 6 7 8 9 10這裡是給a即l陣列賦初值
l[y]
=x y+=
1 build_tree_array(l,p)構建數
print
(get_sum(
4,p)
)#求前4項的和
#input:1 2 3 4 5 6 7 8 9 10
# output:10
上面就是樹狀陣列的內容了 這個資料結構曾經在ccf考試**現過還是比較重要的 也是acm的必修課 求前N項和
再做以前的題目,發現解法其實好多種,雖然萬變不離其宗,可是收穫還是好多。時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 張彤彧 浙江大學 本題要求編寫程式,計算序列 2 1 3 2 5 3 8 5 的前n項之和。注意該序列從第2項起,每...
求陣列的小和
陣列小和定義如下 有一陣列s 1,3,5,2,4,6 在s 0 的左邊小於或等於s 0 的數的和為0,在s 1 的左邊小於或等於s 1 的數的和為1,以此類推,把每個元素的左邊小於或等於當前元素的和加起來,就是該陣列的小和,s的小和為0 1 4 1 6 15 37 如下 public class p...
求陣列的小和
陣列小和的定義 例如,陣列s 1,3,5,2,4,6 在s 0 的左邊小於等於s 0 的數的和為0,在s 1 的左邊小於或等於s 1 的數和為1,在s 2 的左邊小於等於s 2 的數和為1 3 4.一次類推s 3 1,s 4 1 3 2 6,s 5 15,所以s的小和為0 1 4 1 6 15 27...