差分及字首和基礎和例題總結

2021-10-09 07:59:33 字數 2121 閱讀 5278

差分、字首和有著特殊的關係,也是一種入門演算法

首先考慮這樣乙個問題:

有 n 個的正整數放到陣列 a 裡,現在要求乙個新的陣列 b,新陣列的第 i 個數 b[i]是原陣列 a 第 0 到第 i 個數的和。

字首和想必大家都知道,給定一陣列c[i],用另外一陣列sum[n]來儲存c[1]-c[n]的和,這樣在求任意區間的和的時候,就非常的快捷了

具體遞推為

sum[i] = c[i-1]+c[i]

什麼是差分?

差分是兩個元素的差值,我們用乙個新的陣列a[i]記錄差分的值,陣列 a 叫做差分陣列

具體遞推為

a[i] = c[i]-c[i-1]

字首和陣列sum

差分陣列a

差分陣列a的字首和是原陣列

字首和sum的差分陣列是原陣列

在實際的應用當中,對乙個陣列進行操作時,進行區間增加或者減少同樣的數值,就可以直接在差分陣列上進行修改,下次在查詢某個點的值就可以通過差分陣列的來求,十分的快捷

現在有這樣乙個問題

給定乙個n*m大小的矩陣a,有q次詢問,每次詢問給定x1,y1,x2,y2四個數,求以(x1,y1)為左上角座標和(x2,y2)為右下角座標的子矩陣的所有元素和,包括左上角和右下角的元素。

像這樣的題目,我們首先想到的就是遍歷求和,但是如果時多組輸入的話,每次都一遍一遍的計算,很容易tle,所以我們可以在原陣列的基礎上構造二維字首和陣列,求解的話就可以比較快了

如何構造二維字首和陣列?

二維陣列的每個點等於其左邊的點+上邊的點-左上方的點,如果存在就計算,不存在則不計算,比如在邊界上~

在這個圖里,a = b+c-d + a

因為 b 和 c 中都加了一遍d,所以根據容斥原理,把多加的減掉

假如我想求a[2][4]的字首和,我得先加上a[1][4]的字首和,再加上a[2][3]的字首和,然後這個時候我們發現實際上a[1][3]這個部分我們加了兩遍,所以我們需要再減去一遍a[1][3],於是得出公式a[i][j]+=a[i][j-1]+a[i-1][j]-a[i-1][j-1]。

完整**

#include

using

namespace std;

const

int maxn=

1e3+9;

int a[maxn]

[maxn]

;int

main()

for(i=

1;i<=n;i++

)for

(i=1

;i<=q;i++

)}

例題

最高的牛

題意很簡單,我們可以知道一點,在給出的相互能看見的牛對形成的區間是不會交叉的,因為每對牛中間的牛都比他們低

思路:如果兩頭牛看得見則中間的牛h-1,同時使用差分記錄,最後再字首和還原陣列。

#include

using

namespace std;

const

int n =

1e4+10;

int s[n]

;//記錄差分

bool flag[n]

[n];

//此處用int會超記憶體 int是4 個位元組32位,bool只有1位

intmain()

}for

(int i =

1; i <= n; i++

)return0;

}

洛谷字首和例題

字首和 差分詳解及經典例題補充

目錄 字首和 與 差分可以理解為互逆的 求字首和 跟 差分通常設陣列首項下標為1,方便思考的計算。對於一維陣列 a n 存在陣列 sum n 使得 sum i a 1 a 2 a i 以o 1 的時間複雜度得到某塊區間的總和 舉個例子 輸入乙個長度為 n 的整數序列。接下來再輸入 m 個詢問,每個詢...

字首和 差分總結

差分問題總結 一維例題 輸入乙個長度為n的整數序列。接下來輸入m個操作,每個操作包含三個整數l,r,c,表示將序列中 l,r 之間的每個數加上c。請你輸出進行完所有操作後的序列。設那麼求a陣列時,就可以利用b陣列的字首和來計算 在a2 a4區間內每個數加x,就相當於b2加上2,而b3不變,b4也不變...

字首和 差分

數列的字首和 sum i 表示a 1 a i 的和 用處1 求i j的和sum j sum i 1 用處2 區間修改。設定乙個change陣列。當區間 i,j 上要加k時,我們令change i k,令change j 1 k。如果我們對change陣列求字首和的話,字首和sum change i ...