Skip to content

11594: 【原1594】求和

题目

题目描述

author: Spy 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1594

Description

子虚年乌有月,亡是国兵败,亡是公欲割地以求和。

已知:

亡是国疆域内有\(N*M\)座呈矩形分布的封城。

每座封城的人口数由一个二维数组给出\({a[1][1],a[1][2],…,a[N][M]}\).

亡是公有\(Q\)个割地方案,他会给出割地的边界 \(x1,y1,x2,y2\),每个方案中包含的领地是连续的。

对于每个方案包含的人口数量\(a[x1][y1]+a[x1][y1+1]+…+a[x2][y2]\),亡是公希望你帮他求和。

Input Format

第一行有三个整数\(N,M,Q\) ,代表矩形边长和方案数。

接下来 \(N\) 行,每行\(M\) 个数,代表每个城市的人口。

接下来 \(Q\) 行,每行四个整数 \(x1,y1,x2,y2\),代表求和区间。

Output Format

对于每个方案,输出区间内人口数的总和,每个询问输出一行。

Sample Input

3 7 2
5 3 4 8 8 6 3
0 4 1 6 1 3 3
6 2 9 0 4 3 9
1 6 1 7
2 2 3 7

Sample Output

9
45

Limits

对于\(100\%\)的数据,\(\forall i,j, a[i][j]\in [0,2147483647),1\leq x1\leq x2\leq N, 1\leq y1\leq y2\leq M\)。

对于\(60\%\)的数据,\(M*N,Q \leq 10^4\)

对于\(80\%\)的数据,\(M*N \leq 10^7, Q \leq 10^4\)

对于\(100\%\)的数据,\(M*N,Q \leq 10^7\)

BugenZhao's solution

//
// Created by BugenZhao on 2019/3/23.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

using ll=long long;

int main() {
    int N, M, Q;
    cin >> N >> M >> Q;
    auto table = new ll *[N + 1];
    for (int i = 0; i <= N; ++i) {
        table[i] = new ll[M + 1]{};
    }

    int tmp;
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= M; ++j) {
            scanf("%d", &tmp);
            table[i][j] = table[i][j - 1] + table[i - 1][j] - table[i - 1][j - 1] + tmp;
        }
    }

    int x1, y1, x2, y2;
    while (Q--) {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        ll ans = table[x2][y2] - table[x1 - 1][y2] - table[x2][y1 - 1] + table[x1 - 1][y1 - 1];
        if (ans < 0) ans = -ans;
        printf("%lld\n", ans);
    }

    for (int i = 0; i <= N; ++i) {
        delete[] table[i];
    }
    delete[] table;
    return 0;
}

FineArtz's solution

/* 求和 */
#include <iostream>
#include <vector>
using namespace std;

constexpr int MAXS = 5e3 + 5;
long long sum[MAXS][MAXS] = {0};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int m, n, q, t;
    cin >> n >> m >> q;
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            cin >> t;
            sum[i][j] = t + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
        }
    }
    int x1, x2, y1, y2;
    long long ans = 0;
    while (q--){
        cin >> x1 >> y1 >> x2 >> y2;
        ans = sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1];
        cout << ans << '\n';
    }
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cstdio"
using namespace std;

constexpr int max_num = 120000009;

long long a[max_num] = { 0 };
int N, M, Q;
long long f(int posx, int posy) {
    return a[posx * (M + 1) + posy];
}

int main() {

    scanf("%d %d %d", &N, &M, &Q);

    for (int i = 1; i <= N; ++i) {
        a[i * (M + 1)] = a[(i - 1) * (M + 1) + 1];
        for (int j = 1; j <= M; ++j) {
            long long temp;
            scanf("%lld", &temp);
            a[i * (M + 1) + j] = temp + a[(i - 1) * (M + 1) + j]
                + a[i * (M + 1) + j - 1] - a[(i - 1) * (M + 1) + j - 1];
        }
    }

    for (; Q > 0; --Q) {
        int x1, y1, x2, y2;
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        printf("%lld\n", f(x2, y2) - f(x2, y1 - 1) - f(x1 - 1, y2) + f(x1 - 1, y1 - 1));
    }

    return 0;
}

q4x3's solution

#include <stdio.h>
#include <cstring>

using namespace std;

int q[10000010][4];

int main()
{
    int N, M, Q;
    scanf("%d%d%d", &N, &M, &Q);
    int **a;
    long long **map;
    a = new int*[N + 1];
    map = new long long int*[N + 1];
    for(int i = 0;i <= N;++ i) {
        a[i] = new int[M + 1];
        map[i] = new long long[M + 1];
    }
    for(int i = 0;i <= N;++ i)
        for (int j = 0;j <= M;++ j) {
            a[i][j] = 0;
            map[i][j] = 0;
        }
    for(int i = 1;i <= N;++ i)
        for (int j = 1;j <= M;++ j)
            scanf("%d", &a[i][j]);
    for(int i = 1;i <= Q;++ i)
        scanf("%d%d%d%d",&q[i][0],&q[i][1],&q[i][2],&q[i][3]);
    for(int i = 1;i <= N;++ i)
        for(int j = 1;j <= M;++ j)
            map[i][j] = map[i - 1][j] + map[i][j - 1] - map[i - 1][j - 1] + a[i][j];
    for(int i = 1;i <= Q;++ i) {
        printf("%lld\n", map[q[i][2]][q[i][3]] + map[q[i][0] - 1][q[i][1] - 1] - map[q[i][2]][q[i][1] - 1] - map[q[i][0] - 1][q[i][3]]);
    }

}

skyzh's solution

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

int M, N, Q;
int MAP[10000002] = { 0 };
long long SUM[10000002] = { 0 };

int main() {
    scanf("%d%d%d", &N, &M, &Q);
    for (int i = 0, k = 0; i < N; i++) {
        for (int j = 0; j < M; j++, k++) {
            scanf("%d", &MAP[k]);
        }
    }

    SUM[0] = MAP[0];

    for (int j = 1; j < M; j++) {
        SUM[j] = SUM[j - 1] + MAP[j];
    }

    int R = 0;
    for (int i = 1; i < N; i++) {
        R += M;
        SUM[R] = SUM[R - M] + MAP[R];
        for (int j = 1; j < M; j++) {
            int C = R + j;
            SUM[C] = SUM[C - 1] + SUM[C - M] - SUM[C - M - 1] + MAP[C];
        }
    }
    register int x1, y1, x2, y2;
    register long long res = 0;
    register int P_TL, P_BR, P_TR, P_BL;
    for (int i = 0; i < Q; i++) {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        --x1; --y1; --x2; --y2;
        res = 0;
        P_TL = (x1 - 1) * M + (y1 - 1);
        P_BR = x2 * M + y2;
        P_TR = (x1 - 1) * M + y2;
        P_BL = x2 * M + y1 - 1;
        if (x1 == 0 && y1 == 0)
            res = SUM[P_BR];
        else if (x1 == 0)
            res = SUM[P_BR] - SUM[P_BL];
        else if (y1 == 0) 
            res = SUM[P_BR] - SUM[P_TR];
        else {
            res = SUM[P_BR] + SUM[P_TL] - SUM[P_TR] - SUM[P_BL];
        }
        printf("%lld\n", res);
    }
    return 0;
}

WashSwang's solution

#include <iostream>
using namespace std;
int a[10000001],n,m,q,x1,x2,y1,y2;
long long map[10000001],ans;
int main() {
    scanf("%d%d%d",&n,&m,&q);
    for (int i=0;i<n*m;++i){
        scanf("%d",&a[i]);
        if (i>=m) map[i]+=map[i-m];
        if (i%m!=0) map[i]+=map[i-1];
        if (i>=m&&i%m!=0) map[i]-=map[i-m-1];
        map[i]+=a[i];
    }
    for (int i=0;i<q;++i){
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        x1-=1;
        y1-=1;
        x2-=1;
        y2-=1;
        ans=map[x2*m+y2];
        if (y1>0) ans-=map[x2*m+y1-1];
        if (x1>0) ans-=map[(x1-1)*m+y2];
        if (x1>0&&y1>0) ans+=map[(x1-1)*m+y1-1];
        printf("%lld\n",ans);
    }
    return 0;
}