算法合集

68 阅读1分钟

前缀和

蓝桥杯 | 算法基础 前缀和

给定 nn 个正整数组成的数列 a1,a2,...,ana_1,a_2,...,a_nmm 个区间 [l,r][l, r],分别求这 mm 个区间的区间和。

Si1=a1+a2+...+ai1S_{i-1}=a_1+a_2+...+a_{i-1}
Sj=a1+a2+...+ai1+ai+...+ajS_j=a_1+a_2+...+a_{i-1}+a_i+...+a_j
SjSi1=ai+...+ajS_j-S_{i-1}=a_i+...+a_j
#include <bits/stdc++.h>

using std:cin;
using std::cout;

typedef long long ll;
const int kN = 1e5;
ll arr[kN], sum[kN];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> arr[i];
    }
    for (int i = 1; i <= n; ++i) {
        sum[i] = sum[i - 1] + arr[i];
    }
    int m;
    cin >> m;
    while (m--) {
        int l, r;
        cin >> l >> r;
        cout << sum[r] - sum[l - r] << "\n";
    }
    return 0;
}

求矩阵的前缀和

image-20240310205433873

image-20240310210223831

#include <bits/stdc++.h>

using std:cin;
using std::cout;

typedef long long ll;
const int kN = 1e5;
ll arr[kN], sum[kN];

int main() {
    int n, m, q;
    cin >> n >> m >> q;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> arr[i][j];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + arr[i][j];
        }
    }
    while (q--) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        cout << sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1] << "\n";
    }
    return 0;
}