思路

当前的二维前缀和 = sum上面和 + sum下面 - sum(x-1, y-1) + 自己

注意事项

  • i 从 1 开始
  • pre[0].resize(m+1); 注意这里要给 pre[0] 也 resize 一下,不然会一直发生段错误 seg fault!!!

code

#include <iostream>
# include <vector>
using namespace std;

int main() {
    int n, m, q;
    while (~scanf("%d %d %d", &n, &m, &q)) {
        // input
        vector<vector<int>> mat(n+1);
        vector<vector<long long>> pre(n+1);
        pre[0].resize(m+1); // 注意这里要给 pre[0]也 resize 一下,不然会一直发生段错误 seg fault!!!
        for (int i = 1; i <= n; ++i) {
            mat[i].resize(m+1); // mat[i].resize [i] [i] [i]
            pre[i].resize(m+1);
            for (int j = 1; j <= m; ++j) {
                scanf("%d", &mat[i][j]);
            }
        }

        // preprocess
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                pre[i][j] = mat[i][j] + pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1];
            }
        }

        // query
        int x1, y1, x2, y2;
        while(q--) {
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            long long res = pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] + pre[x1-1][y1-1];
            printf("%lld\n", res);
        }
    }
}
// 64 位输出请用 printf("%lld")