差分就是兩個元素的差值
差分陣列是乙個陣列中前後兩個元素的差值構成的陣列。
設原陣列為a[ ],差分陣列為b[ ]
則b[0]=a[0],b[i]=a[i]-a[i-1]
例:
下標 : 012
345 原陣列 a[
]: 532
689差分陣列 b:
5-2-
1421
我們可以發現,通過求差分陣列的字首和就可以得到原陣列
當對乙個陣列的某一部分+或-同乙個數時,可以遍歷,複雜度o(n)。但如果進行許多次這樣的操作,就會tle。
如果用差分就可以快速解決這個問題。
首先要知道,因為是對陣列中的某一部分+或-同乙個數,所以不管加了多少,不管數有多大,這一部分相鄰兩個數的差值是不變的。
其次,因為對差分陣列求字首和可以得到原陣列,所以在求字首和的過程中,一旦差分陣列某個數發生變化,影響的是這個數之後的所有數字,舉例如下:
假設b[1]
+1; 下標 : 012
345新差分陣列b:
5-1-
1421
求字首和:
得到新陣列a:
5437
910對比原陣列a:
5326
89
可以發現是從下標為1的數開始每個數都加了1。
如果我們想讓下標1到下標3的數字加1改怎麼辦呢?
我們可以在差分陣列中下標為4的地方-1,用來消除前面+1的影響。就是下標為1的地方+1導致了從1開始到最後所有的數都加了1,但我們想從4開始保持不變,那我們就在加了1的基礎上減1,所以就是4的地方-1,舉例如下:
假設b[1]
+1 b[4]
-1; 下標 : 012
345新差分陣列b:
5-1-
1411
求字首和:
得到新陣列a:
5437
89對比原陣列a:
5326
89
我們達到了目的。
所以,要想在某一段+或-乙個數(比如從i 到 j +x),就在 i 的地方+x,在j+1的地方-x就好。
這樣操作就很快,不用遍歷。
放一道洛谷上的例題:p2367 語文成績
然後我的ac**:
#include
using
namespace std;
int a[
5000005
],b[
5000005];
intmain()
a[0]
=b[0];
for(
int i=
1;i) a[i]
=b[i]
+a[i-1]
; mi=a[0]
;for
(int i=
1;i) mi=
min(mi,a[i]);
printf
("%d\n"
,mi)
;return0;
}
對Linux inode的一些理解
檔名 inode device block 一 inode是什麼?理解inode,要從檔案儲存說起。檔案儲存在硬碟上,硬碟的最小儲存單位叫做 扇區 sector 每個扇區儲存512位元組 相當於0.5kb 作業系統讀取硬碟的時候,不會乙個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次...
對棧的一些理解
之前總結過一篇有關函式棧幀的部落格 函式棧幀以及呼叫約定相關的一些總結 但是感覺自己還是有一點知識點沒有弄懂,今天中午跟郭哥吃過飯一起 有關殼的問題的時候,順便把這個問題請教了一下郭哥,終於弄明白了,在此要特地感謝他,這裡把一些心得體會寫出來 先看一幅圖 選自ida權威指南 注意圖中是基於esp的棧...
對EK的一些理解
首先是網路流問題的提出 乙個源點,乙個匯點,不斷又源點向匯點輸送,其中路徑上有最大速度,求匯點收貨的最大速度是多少。在求之前可以先模擬一下過程如果源點現在只能出乙個單位的貨,那麼他會找乙個未達到最大速度的路進行運輸,接著我們不斷將運輸的量放大,即不斷地從起點開始尋找增廣路,每次都對其進行增廣,直到源...