取C數組爲修改數組,C[i]表示的是i~n這些元素都加上C[i]這個數
樣例:
ADD(1,3,1)
ADD(2,4,4)
ADD(3,7,3)
咱們對[L,R]區間進行加value操做,在C[L]處加上value,在C[R+1]處減去value
最後求序列的每一個位置變成了多少,只要看一下這個位置上C的前綴和就能夠ios
升級版:對於一個n*m的表格,要求支持操做ADD(x1,y1,x2,y2,a),表示對於以(x1,y1)爲左下角,(x2,y2)爲右上角的矩形區域,每一個元素都加上a。問最後的表格的樣子
和一維版的作法相似。
用數組C存修改信息。在C[x1][y1]處加上a,在C[x2+1][y1]和C[x1][y2+1]處減a,在C[x2+1][y2+1]再加上a。
最後(i,k)位置上的數值就是C數組在(i,k)位置的前綴和。
樹狀數組區間修改單點查詢的時候要用!數組
上述知識點爲我在網上dalao博主找的較好的解釋!spa
我本身對用差分對區間操做的理解,咱們對[L,R]區間進行加value操做,在C[L]處加上value,在C[R+1]處減去value,由於最後要用c數組的前綴和與原始數組分別相加,因此在C[L]處加上value只對L之後數有影響,在L之後的前綴和都加上了value,由於要求的做用範圍是[L,R],因此R之後的前綴和不能產生影響,則應該在C[R+1]處減去value,以與前面加的value相抵消。二維數組同理。code
下面是我遇到的例題:orm
上交大OJ 1002:二哥種花生xml
二哥在本身的後花園裏種了一些花生,也快到了收穫的時候了。這片花生地是一個長度爲L、寬度爲W的矩形,每一個單位面積上花生產量都是獨立的。他想知道,對於某個指定的區域大小,在這麼大的矩形區域內,花生的產量最大會是多少。blog
第1行有2個整數,長度L和寬度W。圖片
第2行至第L+1行,每行有W個整數,分別表示對應的單位面積上的花生產量A( 0≤A<10 )。ip
第L+2行有2個整數,分別是指定的區域大小的長度a和寬度b。ci
輸出一個整數m,表示在指定大小的區域內,花生最大產量爲m。
4 5 1 2 3 4 5 6 7 8 0 0 0 9 2 2 3 3 0 0 0 1 3 3
38
左上角:38 = (1+2+3) + (6+7+8) + (0+9+2)
對於30%的數據: 1≤L,W≤100;
對於100%的數據: 1≤L,W≤1000。
所有區域大小知足:1≤a≤L,1≤b≤W 。
分析:這裏就用到前綴和來求解遍歷,以防超時!
AC code:
1 #include <iostream> 2 using namespace std; 3 const int maxn = 1000 + 5; 4 int c[maxn][maxn] = {0}; 5 int main() { 6 int L, W; 7 cin >> L >> W; 8 for(int i = 1; i <= L; i++) 9 for(int j = 1; j <= W; j++) { 10 cin >> c[i][j]; 11 c[i][j] = c[i][j] + c[i][j-1] + c[i-1][j] - c[i-1][j-1]; //求前綴和 12 } 13 14 int a, b; 15 long max=0, sum; 16 cin >> a >> b; 17 18 for( int i = 1; i <= L - a + 1; i++) { 19 for(int j = 1; j <= W - b + 1; j++) { 20 sum = c[i+a-1][j+b-1] - c[i-1][j+b-1] - c[i+a-1][j-1] + c[i-1][j-1]; 21 if(sum > max) 22 max = sum; 23 } 24 } 25 cout << max; 26 return 0; 27 }