smile, breathe and go slowly.引入問題:
已知乙個陣列 a[ 10 ] ,初始值全部為1。 如果要將範圍 [ 1, 5 ]之間的每乙個數字都加1,應當如何操作。
最簡單直接的操作就是for迴圈了:
for
(int i=
1;i<=
5;i++
) a[i]
++;
但是如果資料範圍較大,以及操作次數比較多,用for迴圈時間複雜度較高。
先看看什麼是差分陣列:
簡單來說,前乙個元素減去後乙個元素形成的陣列就是差分陣列。
d[ 0 ] = a[ 0 ] ( i = 0 )
d[ i ] = a[ i ] - a[ i - 1 ] ( i > 0)
舉個例子:
陣列 a:
1,2,3,4,5
差分陣列 d 應當是:
1,1,1,1,1
//第乙個元素沒有可以減的元素,所以就等於它本身
//即規定d[ 0 ] = a[ 0 ]
我們注意到:
d[ 1 ] = a[ 1 ] - a[ 0 ]
d[ 2 ] = a[ 2 ] - a[ 1 ]
d[ 3 ] = a[ 3 ] - a[ 2 ]
d[ 4 ] = a[ 4 ] - a[ 3 ]
即:a[ 0 ] = d[ 0 ]
a[ 1 ] = d[ 1 ] + d[ 0 ]
a[ 2 ] = d[ 2 ] + d[ 1 ] + a[ 0 ]
…
可推導出 a[ i ] = d[ i ] + d[ i - 1 ] + d[ i - 2 ] + …+d[ 0 ]
所以差分陣列到底有什麼用呢?
回到引入問題:
要使[ 1, 5 ] 之間的每個元素都+1,用差分陣列只需要這樣寫:
d[1]
++;d[5
+1]--
;
因為d[ 1 ] = a[ 1 ] - a[ 0 ],a[ 1 ]增大了,a[ 0 ]不變,所以d[ 1 ]應當加上相應的變化量。
同理,中間的元素是同步增大的,所以無需處理。
對於d [ 6 ] = a[ 6 ] - a[ 5 ],a[ 5 ]增大了,a[ 6 ]不變,所以d[ 6 ]應當減去相應的變化量。
原本複雜的for迴圈,現在只需兩行**。
差分陣列不僅僅是乙個優秀的資料結構,還是一種很好的思想。
修改區間的時間複雜度是o(1),查詢點的時間複雜度為o(n)
對應練習題:
基礎題: cf44c holidays(差分陣列)
高階題:p4939 agent2(樹狀陣列+差分陣列)。
基礎題** (python版):
n, m =
input()
.split(
)n, m=
int(n)
,int
(m)out=
falsed=[
0for i in
range(0
,n+2)]
#d為差分陣列
for i in
range(0
,m):
a, b=
input()
.split(
) a, b=
int(a)
,int
(b) d[a]+=1
#差分陣列的更新
d[b+1]
-=1for i in
range(1
,n+1):
count=
sum(d[
0:i+1]
)#求第i天澆水的次數
if count!=1:
#澆水次數不等於1就輸出,結束
print
(i,count)
out=
true
break
ifnot out:
#沒有問題就輸出ok
print
("ok"
)
#include
using
namespace std;
int d[
10000002];
int n, m;
intlowbit
(int x)
intgetsum
(int a)
return sum;
}void
update
(int a,
int b)
for(
int i = b+
1; i <= n; i +
=lowbit
(i))
}int
main()
else
}return0;
}
差分陣列詳解
學習部落格 題目 來先看一道裸題,有n個數。m個操作,每一次操作,將x y區間的所有數增加z 最後有q個詢問,每一次詢問求出x y的區間和。思路 很明顯,直接用字首和無法快速滿足這個操作,所以我們就用到了差分陣列。設a陣列表示原始的陣列 設d i a i a i 1 1設f i f i 1 d i ...
演算法筆記 差分陣列
差分陣列是什麼呢?差分陣列是字首和的逆運算,同樣運用到容斥原理 一維 l r a l a r 1 二維 x1 x2 y1 y2 a x1 y1 a x1 y2 1 a x2 1 y1 a x2 1 y2 1 三維 x1 x2 y1 y2 z1 z2 a x1 y1 z1 a x2 1 y1 z1 a...
差分陣列分析詳解 例題
差分,又名差分函式或差分運算,差分的結果反映了離散量之間的一種變化。例如,我們有一段離散化序列 a 1 a 2 a 3 a n 1 a n 我們可以建立數列的每一項與前一項的差值陣列 c,則有 c 1 a 1 a 0 當 i 2 時有 c i a i a i 1 這樣我們就可以將一段序列的差值序列記...