2021 年 Q3 iOS 遊戲下載測算榜:《王者榮耀》登頂,《哈利波特:魔法覺醒》表現最佳
一維差分
輸入一個長度為n的整數序列。
接下來輸入m個操作,每個操作包含三個整數l,r,c,表示將序列中[l,r]之間的每個數加上c。
請你輸出進行完所有操作後的序列。
輸入格式
第一行包含兩個整數n和m。
第二行包含n個整數,表示整數序列。
接下來m行,每行包含三個整數l,r,c,表示一個操作。
輸出格式
共一行,包含n個整數,表示最終序列。
資料範圍
1≤n,m≤100000,
1≤l≤r≤n,
−1000≤c≤1000,
−1000≤整數序列中元素的值≤1000
輸入樣例:
6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1
輸出樣例:
3 4 5 3 4 2
對於差分只需要構造bn,使得∑bn=an即可,即a陣列是b陣列的字首和。
即:b1 = a1
b2 = a2 - a1
b3 = a3 - a2
......
bn = an - an-1
因此,只要有b陣列,就可以在O(N)時間內得到a陣列。
差分陣列b的作用就可以實現使得陣列a在[l,r]區間內加上c的操作,假設讓bl加上c,那麼從al到an都會加上c,因為使用bi陣列求ai的時候是使用b1~bi累加求出來的。
故對於要在陣列a[l,r]區間上實現加c的操作,只需要從bl加上c,然後從br+1的位置減去c即可。
1 #include <iostream> 2 using namespace std; 3 const intN = 100009; 4 int a[N],b[N]; 5 void insert(int l,int r,int c) 6 { 7 b[l] += c; 8 b[r + 1] -= c; 9 } 10 int main() 11 { 12 int n , m; 13 cin >> n >> m; 14 for(int i = 1;i <= n;++i) 15 { 16 cin >> a[i]; 17 insert(i,i,a[i]); 18 } 19 while(m--) 20 { 21 int l,r,c; 22 cin >> l >> r >> c; 23 insert(l,r,c); 24 } 25 for(int i = 1;i <= n;++i) 26 { 27 b[i] += b[i-1]; 28 cout << b[i] << " "; 29 } 30 return 0; 31 }
二維差分矩陣
輸入一個n行m列的整數矩陣,再輸入q個操作,每個操作包含五個整數x1,y1,x2,y2,c,其中(x1,y1)和(x2,y2)表示一個子矩陣的左上角座標和右下角座標。
每個操作都要將選中的子矩陣中的每個元素的值加上c。
請你將進行完所有操作後的矩陣輸出。
輸入格式
第一行包含整數n,m,q。
接下來n行,每行包含m個整數,表示整數矩陣。
接下來q行,每行包含5個整數x1,y1,x2,y2,c,表示一個操作。
輸出格式
共n行,每行m個整數,表示所有操作進行完畢後的最終矩陣。
資料範圍
1≤n,m≤1000,
1≤q≤100000,
1≤x1≤x2≤n,
1≤y1≤y2≤m,
−1000≤c≤1000,
−1000≤矩陣內元素的值≤1000
輸入樣例:
3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1
輸出樣例:
2 3 4 1
4 3 4 1
2 2 2 2
案發時發生簡單快捷
矩陣差分比較麻煩,因為是二維,因此b陣列比較難以構造,但是先拋開b陣列是什麼樣的形式,假設b陣列的字首和就是a,是已知的,那麼接下來來看看是如何實現大矩陣中小矩陣塊的操作。
知道了如何操作之後,其實如何構造b陣列已經不重要了,只需要像一維差分中的insert一樣利用這一個操作過程,即可實現b陣列的構造。
至於a陣列的求值參考二維的字首和即可。
1 #include <iostream> 2 using namespace std; 3 const int N = 1009; 4 int a[N][N],b[N][N]; 5 6 void insert(int x1,int y1,int x2,int y2,int c) 7 { 8 b[x1][y1] += c; 9 b[x2 + 1][y1] -=c; 10 b[x1][y2 + 1] -=c; 11 b[x2 + 1][y2 + 1] +=c; 12 } 13 14 int main() 15 { 16 int n,m,q; 17 cin >> n >> m >> q; 18 for(int i = 1;i <= n;++i) 19 { 20 for(int j = 1;j <= m;++j) 21 { 22 cin >> a[i][j]; 23 insert(i,j,i,j,a[i][j]); 24 } 25 } 26 27 while(q--) 28 { 29 int x1,y1,x2,y2,c; 30 cin >> x1 >> y1 >> x2 >> y2 >> c; 31 insert(x1,y1,x2,y2,c); 32 } 33 34 for(int i = 1;i <= n;++i) 35 { 36 for(int j = 1;j <= m;++j) 37 { 38 b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]; 39 cout << b[i][j] << " "; 40 } 41 cout << endl; 42 } 43 return 0; 44 }