演算法基礎 差分陣列詳解

2021-10-01 03:45:26 字數 2624 閱讀 4528

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 這樣我們就可以將一段序列的差值序列記...