1.一维前缀和:
#include <iostream> using namespace std; const int N = 1e5 + 10; int n, m; int a[N], s[N]; int main() { // ios::sync_with_stdio(false); // 提高cin的读取速度,但不能使用scanf scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 0; i <= n; i++) s[i] = s[i - 1] + a[i]; while (m--) { int l, r; scanf("%d%d", &l, &r); printf("%d\n", s[r] - s[l - 1]); } return 0; }
2.二维前缀和:
#include <iostream> using namespace std; const int N = 1010; int n, m, q; int a[N][N], s[N][N]; int main() { scanf("%d%d%d", &n, &m, &q); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &a[i][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; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); printf("%d\n", s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]); // 算子矩阵的和 } return 0; }
3.一维差分
#include <iostream> using namespace std; const int N = 1e5 + 10; int n, m; int a[N], b[N]; int main() { scanf("%d%d", &n, &m); a[0] = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = a[i] - a[i - 1]; // 差分 } while (m--) { int l, r, c; scanf("%d%d%d", &l, &r, &c); b[l] += c; b[r + 1] -= c; } b[0] = 0; for (int i = 1; i <= n; i++) { a[i] = a[i - 1] + b[i]; } for (int i = 1; i <= n; i++) { printf("%d ", a[i]); } return 0; }
4.二维差分
// 差分 #include <iostream> using namespace std; const int N = 1010; int n, m, q; int a[N][N], b[N][N]; int main() { scanf("%d%d%d", &n, &m, &q); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &a[i][j]); b[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1]; // 差分 } } while (q--) { int x1, y1, x2, y2, c; scanf("%d%d%d%d%d", &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++) { a[i][j] = a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j]; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { printf("%d ", a[i][j]); } printf("\n"); } return 0; }