前綴和

普通

簡介

前綴和是一種用來快速求取陣列中某個區間和的技巧。概念就是讓前綴和陣列的第 ii 個元素儲存前 ii 個元素的總和,這樣就可以在 O(1)O(1) 的時間透過兩個前綴和相減來求取區間和。

基本前綴和

首先,我們需要一個陣列 psumpsum 來儲存前綴和,其中 psum[i]psum[i] 儲存的是陣列 aa 的前 ii 個元素的總和。

接著,我們可以用以下的程式碼來建立前綴和陣列。

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

最後,我們可以用以下的方法來求取陣列 aa 中從第 ll 個元素到第 rr 個元素的區間和。

int sum = psum[r] - psum[l - 1];

這個技巧在之後的題目中會經常用到!

二維前綴和

如果是二維陣列,我們一樣可以透過前綴和的技巧來存取某個子矩陣的總和。

首先,我們需要一個二維陣列 psumpsum 來儲存前綴和,其中 psum[i][j]psum[i][j] 儲存的是二維陣列 aa 的左上角 (1,1)(1, 1) 到右下角 (i,j)(i, j) 的總和。

接著,我們可以用以下的程式碼來建立二維前綴和陣列。

for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        psum[i][j] = psum[i - 1][j] + psum[i][j - 1] - psum[i - 1][j - 1] + a[i][j];
    }
}

也許你會好奇為上面那個算式是怎麼來的,因為根據排容原理,我們要計算的 psum[i][j]psum[i][j],可以透過把 psum[i1][j]psum[i - 1][j]psum[i][j1]psum[i][j - 1] 加起來,再減掉 psum[i1][j1]psum[i - 1][j - 1] 來得到。

alt text