ACWing 795. 前缀和(C++)

ACWing 795. 前缀和(C++)

题目原文

ACWing 795. 前缀和(原题链接)

题目描述
输入一个长度为 n n n的整数序列。

接下来再输入 m m m个询问,每个询问输入一对 l l l, r r r

对于每个询问,输出原序列中从第 l l l个数到第 r r r个数的和。

输入格式
第一行包含两个整数 n n n m m m

第二行包含 n n n个整数,表示整数数列。

接下来 m m m行,每行包含两个整数 l l l r r r,表示一个询问的区间范围。

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

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

输入样例:

5 3
2 1 3 6 4
1 2
1 3
2 4

输出样例:

3
6
10

解题思路

首先,本题可轻易想到暴力解法,即每次输入 l , r l,r l,r都对数组从 a [ l ] a[l] a[l] 累加至 a [ r ] a[r] a[r]。但注意到本题的数据范围,若使用此方法时间复杂度为 O ( m n ) O(mn) O(mn) ,操作次数可能会多达 1010,过于耗时,因此我们想办法改进。

注意到,若已知 a [ i ] a[i] a[i] 数组,我们可在 O ( n ) O(n) O(n) 复杂度求得其前缀和数组 s [ i ] s[i] s[i] 。而在每次操作中,利用公式:

s [ r ] − s [ l − 1 ] = a [ l ] + a [ l + 1 ] + . . . . . . + a [ r − 1 ] + a [ r ] s[r] - s[l - 1] = a[l] + a[l + 1] + ...... + a[r - 1] + a[r] s[r]s[l1]=a[l]+a[l+1]+......+a[r1]+a[r]

即可一次操作求得原序列中从第 l l l 个数到第 r r r 个数的和。改进后的算法最终时间复杂度应为 O ( n + m ) O(n+m) O(n+m)

代码

#include <iostream>

using namespace std;

const int N = 1e5 + 10;
int a[N], s[N];

int main()
{
    int n, m;
    cin >> n >> m;
    
    for (int i = 1; i <= n ; i ++ )
    {
        cin >> a[i];
        s[i] = s[i - 1] + a[i];
    }
    
    while (m -- )
    {
        int l, r;
        cin >> l >> r;
        cout << s[r] - s[l - 1] << endl;
    }
    
    return 0;
}

后记

提示:在输入输出数据数量很大时用scanf,printf 替换cin,cout 可以减少程序运行时间。

ACWing 网站提交本程序后发现程序的运行时间还是比较长,达到了 1004 m s 1004ms 1004ms ,于是将算法中 cin,cout 改成了scanf,printf,发现运行时间明显变短,变为了 168 m s 168ms 168ms

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星月满空江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值