字首和 二維字首和與差分的小總結

2021-08-24 20:25:02 字數 2703 閱讀 7829

在了解二維字首和之前,我們首先需要了解一下什麼是字首和。

如果我給你一串長度為n的數列a1,a2,a3......an,再給出m個詢問,每次詢問給出l,r兩個數,要求給出區間[l,r]裡的數的和,你會怎麼做,若是沒有了解過字首和的人看到這道題的想法可能是對於m次詢問,我每次都遍歷一遍它給的區間,計算出答案,這樣子的方法固然沒錯,但是其時間複雜度達到了o(n*m),如果資料量稍微大一點就有可能超時,而我們如果使用字首和的方法來做的話就能夠將時間複雜度降到o(n+m),大大節省了運算時間。至於怎麼用,請看下面一小段**

a[0]=0;

for(int i=1;i<=n;i++)a[i]+=a[i-1];

沒錯,字首和顧名思義就是前面i個數的總和。陣列a在經過這樣的操作之後,對於每次的詢問,我們只需要計算a[r]-a[l-1]就能得到我們想要的答案了,是不是很簡單呢。

在知道了最簡單的字首和之後,我們再來了解一下什麼是差分。

給你一串長度為n的數列a1,a2,a3......an,要求對a[l]~a[r]進行m次操作:

操作一:將a[l]~a[r]內的元素都加上p

操作二:將a[l]~a[r]內的元素都減去p

最後再給出乙個詢問求a[l]-a[r]內的元素之和?

你會怎麼做呢?你可能會想,我對於m次操作每次都遍歷一遍a[l]~a[r],給區間裡的數都加上p或減去p,最後再求一次字首和就行了。沒錯,這樣子確實也能得出正確答案,但時間複雜度卻高達o(m*n),對於1<=n,m<=1e5這個資料範圍來說直接就tle了,所以說這個方法不可行。既然這樣不行的話,那我們要怎麼做才能快速的得到正確答案呢?是的,這個時候我們的差分就該派上用場了,我們新開乙個陣列b,儲存每一次的修改操作,最後求字首和的時候統計一下就能快速的得到正確答案了,詳細請看下面**。

#includeusing namespace std;

const int maxn=1e5+9;

int a[maxn],b[maxn];

int main()

for(i=1;i<=m;i++)

else

} int add=0;

for(i=1;i<=n;i++)

int x,y;

cin>>x>>y;

cout相信看到這裡,大家已經仔細思考過**了,為什麼操作一時b[r+1]要減去p,很簡單,因為操作一我只需對[l,r]區間裡的數加p,[r+1,n]這個區間裡的數沒必要加p,所以需要減掉p。

差分講解完畢,接下來我們終於要開始今天的正題——二維字首和了。

還是以小問題的形式來講解二維字首和吧。

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

怎麼做呢?為了方便你們理解,我畫個圖吧。

圖畫的很醜,希望不要介意。如圖所示,按題目要求,我們每次要求的答案就是紅色圓圈所在的區域的值(注意,這裡的x1,x2表示行,y1,y2表示列),對比上面這張圖我們能夠發現紅色區域的值等於四個區域的值減去(白色區域+黑色區域),再減去(白色區域+藍色區域),最後因為白色區域被減了兩次,我們需要再加回來。所以ans=a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1];(注意,此時的a陣列代表的是字首和)。突然想起來還沒說怎麼求二維字首和,很簡單,看下面**。

for(int i=1;i<=n;i++)

為方便理解貼個圖

假如我想求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]

接下來看完整**吧。

#includeusing 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++)

好了,一維字首和、二維字首和、差分都說完了,希望看這篇文章的人能夠有所收穫吧。

地毯 二維差分和二維字首和

見 類似於一維差分,o 1 的時間複雜度。二維差分相關概念 均是搬運 當對乙個二維區間內的所有數做出全部加乙個數或者全部減乙個數的操作時,需要修改二維差分矩陣內的四個點。比如我想讓a x1 y1 和a x2 y2 兩對角頂點圍成的矩形區域內的所有點都加1,則我需要 讓a x1 y1 a x1 y2 ...

一維字首和與二維字首和

什麼是字首和?字首和是乙個陣列的某項下標之前 包括此項元素 的所有陣列元素的和。作用 快速求出某一段區間的總和 such as 求出a 3 a 4 a 15 sum 15 sum 2 sum為字首和 優勢 可以在o 1 的複雜度求出某一部分的總和 設b為字首和陣列,a為原陣列,根據這句話可以得到字首...

動態差分 二維字首和 小a的轟炸遊戲

小a正在玩一款即時戰略遊戲,現在他要用航空母艦對敵方陣地進行轟炸 地方陣地可以看做是n m n mn m的矩形 航空母艦總共會派出q qq架飛機。飛機有兩種,第一種飛機會轟炸以 xi yi xi,yi xi,yi 為中心,對角線長為l i lili的正菱形 也就是兩條對角線分別於x xx軸 y yy...