AcWing 795:一维前缀和

【题目来源】
https://www.acwing.com/problem/content/797/

【问题描述】
输入一个长度为 n 的整数序列。
接下来再输入 m 个询问,每个询问输入一对 l,r。
对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。

【输入格式】
第一行包含两个整数 n 和 m。
第二行包含 n 个整数,表示整数数列。
接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。

【输出格式】
共m行,每行输出一个询问的结果。

【数据范围】
1 ≤ l ≤ r ≤ n,
1 ≤ n , m ≤ 100000,
− 1000 ≤ 数 列 中 元 素 的 值 ≤ 1000;

【输入样例】
5 3
2 1 3 6 4
1 2
1 3
2 4

【输出样例】
3
6
10

【算法分析】
● 一维前缀和
(一)什么是一维前缀和?
一维前缀和非常简单,简单到一句话就能说清楚。即,一个长度为 n 的一维数组 a[1]~a[n],其一维前缀和
sum[i]=a[1]+a[2]+...+a[i]。这么简单?需要专门学?需要,因为利用前缀和可以提高计算效率,不学就想不到。一维前缀和能够把时间复杂度为 O(n) 的区间计算优化为 O(1) 的端点计算
(二)一维前缀和,通常用于快速计算 [le, ri] 中数据的“区间和”。
利用“一维前缀和”,快速计算 [le, ri] 中数据的“区间和”的步骤为:
(1)利用给定的数据 a[i],预处理出一个“
前缀和数组”:sum[i]=sum[i-1]+a[i]   (1≤i≤n)
(2)通过查表“前缀和数组”,快速计算位于 [le, ri] 中数据的“区间和”:sum[ri]-sum[le-1]   (ri≥le)

● 二维前缀和
二维前缀和数组预处理过程:sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]
二维区间和计算过程:sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]      (y2≥y1,x2≥x1)

【算法代码】

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

const int maxn=100010;

int a[maxn], s[maxn];

int main() {
    int n, m;
    scanf("%d%d", &n, &m);

    for(int i=1; i<=n; i++) {
        scanf("%d", &a[i]);
        s[i]=s[i-1]+a[i];
    }

    while(m--) {
        int le, ri;
        scanf("%d%d", &le, &ri);

        printf("%d\n",s[ri]-s[le-1]);
    }

    return 0;
}



/*
in:
5 3
2 1 3 6 4
1 2
1 3
2 4

out:
3
6
10
*/



【参考文献】
https://blog.youkuaiyun.com/hnjzsyjyj/article/details/120265452
https://blog.youkuaiyun.com/weixin_45776544/article/details/115334481



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值