取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的前綴和就可以
升級版:對於一個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博主找的較好的解釋!
我自己對用差分對區間操作的理解,我們對[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相抵消。二維數組同理。
下面是我遇到的例題:
上交大OJ 1002:二哥種花生
Description
二哥在自己的后花園里種了一些花生,也快到了收獲的時候了。這片花生地是一個長度為L、寬度為W的矩形,每個單位面積上花生產量都是獨立的。他想知道,對於某個指定的區域大小,在這么大的矩形區域內,花生的產量最大會是多少。
Input Format
第1行有2個整數,長度L和寬度W。
第2行至第L+1行,每行有W個整數,分別表示對應的單位面積上的花生產量A( 0≤A<10 )。
第L+2行有2個整數,分別是指定的區域大小的長度a和寬度b。
Output Format
輸出一個整數m,表示在指定大小的區域內,花生最大產量為m。
Sample Input
4 5
1 2 3 4 5
6 7 8 0 0
0 9 2 2 3
3 0 0 0 1
3 3
Sample Output
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 }

