1. 程式人生 > >差分陣列的總結

差分陣列的總結

差分陣列的資料網上不太好找,蒟蒻表示網上學習這個自認為比較簡單的技巧是比較麻煩的,於是蒟蒻覺得自己寫下學習總結。

部落格上看拉個題目意思大概是:

給定一個長度為N的序列: 首先進行X次操作,每次操作在Li和Ri這個區間加上一個數Ci。
然後進行Y次詢問,每次詢問Li到Ri的區間和。
初始序列都為0。
1<=N<=1000000,1<=X<=N, X<=Y<=N
1<=Li<=N,Li<=Ri<=N,|Ci|<=100000000000000

很多人第一眼看到這個題目第一反應都是線段樹的裸題?但是本人認為線段樹對於蒟蒻來說在大考中程式碼實現複雜,如果寫的不太熟悉的話,運用大量時間去實現其是不夠理智的,不過對於這個題利用差分陣列解題是個不錯的選擇。

差分陣列(差分數列):

對於一個數組A[ ],其差分陣列D[i]=A[i]-A[i-1] (i>0)且D[0]=A[0]

令SumD[i]=D[0]+D[1]+D[2]+…+D[i] (SumD[ ]是差分陣列D[ ]的字首和)
則SumD[i]=A[0]+A[1]-A[0]+A[2]-A[1]+A[3]-A[2]+…+A[i]-A[i-1]=A[i]
即A[i]的差分陣列是D[i], 而D[i]的字首和是A[i]

對於“數列遊戲”這題: 如果每次修改都修改從L到R的值的話,一定會TLE。
注意特殊處:這道題是先進行整體區間修改,最後才統一查詢。 所以,我們只要維護一個差分陣列就行了。
維護差分陣列,對於將區間[L,R]加C,我們只需要將D[L]+C和D[R+1]-C 當修改完畢後,我們先求一遍差分字首和就得到了修改後的陣列A[ ],
然後再對A[ ]求一遍字首和
這樣每次查詢的時候只要計算一次就可以得到結果了

總的來說差分陣列適用於離線區間修改問題,如果是線上的話應該用線段樹或其他資料結構。

差分陣列其實就相當於通過改變區間前端和末端與其他部分的差值,在最後進行累加的時候實行對整個區間的值的改變。

但為什麼要存差值呢?————因為數列中的數滿A[i]=sum{D[1]…D[i]},便於用遞推求得最後的值。

實現的程式碼就不提供啦(做完題目很久才寫的部落格是在是罪過啊)