← 返回题目页

A1073 二维差分2

标程

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;

    // 多开两行两列,让越界的角点改动也有地方放
    vector<vector<int>> a(n + 2, vector<int>(m + 2, 0));
    vector<vector<int>> d(n + 2, vector<int>(m + 2, 0));

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
        }
    }

    // 二维差分:d[i][j] = a[i][j] - a[i-1][j] - a[i][j-1] + a[i-1][j-1]
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            d[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1];
        }
    }

    // 每个元素占 3 个场宽,矩阵之间空一行
    auto printMatrix = [&](const vector<vector<int>> &g) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                printf("%3d", g[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    };

    printMatrix(d);   // 第一组:初始的二维差分数组

    int q;
    cin >> q;
    for (int k = 0; k < q; k++) {
        int x1, y1, x2, y2, x;
        cin >> x1 >> y1 >> x2 >> y2 >> x;
        // 矩形 [x1..x2] × [y1..y2] 加 x:只改差分的四个角
        d[x1][y1] += x;
        d[x2 + 1][y1] -= x;
        d[x1][y2 + 1] -= x;
        d[x2 + 1][y2 + 1] += x;
        printMatrix(d);
    }

    // 最后一组:二维前缀和还原出的最终矩阵
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
        }
    }
    printMatrix(d);

    return 0;
}

动画演示