一维差分




// 一维差分
#include<bits/stdc++.h>
using namespace std;
const int N = 5;
int arr[N] = {1,6,2,8,5};
int d[N] = {0} ; int sum[N] = {0};
void add(int arr[], int l , int r , int v){
if(l >=0 && r < N){
arr[l] += v;
if(r != N-1){
arr[r+1] -= v;
}
}
}
int main(){
d[0] = arr[0];
for(int i = 1 ; i < N ; i++){ // 求差分数组d
d[i] = arr[i]-arr[i-1];
}
add(d, 1, 3, 3); // 对差分数组进行处理
for(int i = 1 ; i < N ; i++){
if(i-1 == 0){
sum[i-1] = arr[i-1];
cout << sum[i-1] << " ";
}
sum[i] = d[i]+sum[i-1]; // 得到最后答案啦
cout << sum[i] << " ";
}cout << endl;
return 0;
}
链接:【STUACM-算法入门-前缀和与差分(含二维)】https://www.bilibili.com/video/BV1pi4y1j7si?p=2&vd_source=1bdf2769003824b5e26162b237ab82d5
二维前缀和
1 | 2 | 7 | 9 |
2 | 7 | 6 | 3 |
2 | 1 | 1 | 5 |
求第一行的1-3和第二行1-3的总和
// 二维前缀和
#include<bits/stdc++.h>
using namespace std;
const int hang = 3;
const int lie = 4;
int arr[hang][lie];
int sum[hang][lie] = {0};
int sumnum = 0;
int add(int sum[], int l, int r){
if(l >= 0 && r < lie){ //判断区间的合法性
if(l == 0){
return sum[r];
}
else{
return sum[r]-sum[l-1]; //求对应区间的总和数值
}
}
return 0;
}
int main(){
for(int i = 0 ; i < hang ; i++){ // 输入要的数据
for(int j = 0 ; j < lie ; j++){
cin >> arr[i][j];
}
}
for(int i = 0 ; i < hang ; i++){ // 对第一列进行特殊化处理
sum[i][0] = arr[i][0];
}
for(int i = 0 ; i < hang ; i++){
for(int j = 1 ; j < lie ; j++){
sum[i][j] = sum[i][j-1] + arr[i][j];
} // 求各个和数列
}
int sum1 = add(sum[0], 1, 3);
int sum2 = add(sum[1], 1, 3);
sumnum = sum1 + sum2;
cout << "第一行1-3和第二行的1-3总和为" << sumnum << endl;
return 0;
}
// 二维前缀和
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int s[N][N], a[N][N];
int main(){
int n, m, q ; cin >> n >> m >> q;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= m ; j++){
cin >> a[i][j];
}
}
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++){
s[i][j] = s[i-1][j] + s[i][j-1];
}
}
while(q--){
int x1, x2, y1, y2 ; cin >> x1 >> x2 >> y1 >> y2;
cout << s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1] << endl;
}
return 0;
}