求前缀和:\(s_{i, \: j} = s_{i - 1, \: j} + s_{i, \: j - 1} - s_{i - 1, \: j - 1} + a_{i, \: j}\)
算部分和:\(s_{x_2, \: y_2} - s_{x_1 - 1, \: y_2} - s_{x_2, \: y_1 - 1} + s_{x_1 - 1, \: y_1 - 1}\)
#include <bits/stdc++.h>
using namespace std;
const char nl = ‘\n‘;
const int N = 1000 + 50;
int a[N][N], s[N][N];
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
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 <= m; ++j)
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
while (q--){
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
cout << s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1] << nl;
}
return 0;
}
\(b_{x_1, \: y_1} \: += \: c\)
\(b_{x_2 + 1, \: y_1} \: -= \: c\)
\(b_{x_1, \: y_2 + 1} \: -= \: c\)
\(b_{x_2 + 1, \: y_2 + 1} \: += \: c\)
#include <bits/stdc++.h>
using namespace std;
const char nl = ‘\n‘;
const int N = 100 + 50;
int a[N][N], b[N][N];
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
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 <= m; ++j){
b[i][j] += a[i][j];
b[i + 1][j] -= a[i][j];
b[i][j + 1] -= a[i][j];
b[i + 1][j + 1] += a[i][j];
}
}
// 区间操作
while (q--){
int x1, y1, x2, y2, c;
cin >> x1 >> y1 >> x2 >> y2 >> c;
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}
// 计算前缀和
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
// 输出
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j) cout << b[i][j] << ‘ ‘;
cout << nl;
}
return 0;
}
原文:https://www.cnblogs.com/xiaoran991/p/14406679.html