鳴謝 這位爺。html
前綴和與差分是比較簡單常常用到做爲預處理的大手子出如今各大場所而且是一對搭檔。數組
一維的簡簡單單,二維的有點複雜。spa
從一個\(2 \times 2\)的矩陣開始看,從左上角到紅色部分的前綴和確定是由兩個黃色部分加兩個綠色部分作成的,左上角到黃色部分的前綴和很顯然是一維前綴和作出來的,因此左上角到紅色部分的前綴和很顯然是由兩個一維前綴和加起來減掉一個多加的的綠色部分,而後就能夠拓展:
紅色部分的前綴和顯然由藍色的加黃色的減去多加的綠色。htm
公式:
\[sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]\]blog
而後求出前綴和以後怎麼\(O(1)\)去查詢呢?
如圖所示,求紫色部分值,顯然由黃色部分的前綴和減去兩個藍色部分的前綴和,再加上一個多減去的綠色部分。
公式:
\[sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]\]get
而後二維差分就是他的兄弟.。由於差完分還原值的時候是經過對差分數組作前綴和進行還原,因此差分的時候也是根據前綴和的性質去差分。
要在紫色部分加上一個值,因此首先在開始處\((x1,y1)\)加上一個值,根據前綴和的性質,此次增長值影響到了從\((x1,y1)\)到右下角的矩陣,超出了要修改的範圍,因此爲了給兩個藍色消除影響,應該在\((x1,y2+1)\)和\((x2+1,y2)\)處加上要修改值的相反數。可是這樣的話會多消一個綠色區域,因此要在\((x2+1,y2+1)\)加上要修改的值來消除多消的影響。
公式:
\[dif[x1][y1]+=a,dif[x1][y2+1]-=a,dif[x2+1][y1]-=a,dif[x2+1][y2+1]+=a\]class
又懂了。im