一维前缀和

前缀和算法是一种常用的算法,它可以用来快速计算一个数组中某个区间内的元素和。在本文中,我们将介绍前缀和算法的原理、实现方法以及应用例子。

一、前缀和算法的原理

前缀和算法的原理很简单,就是先计算出数组的前缀和,然后通过前缀和的差值来计算出任意区间的元素和。具体来说,我们可以用一个数组sum来存储原数组的前缀和,即sum[i]表示原数组中前i个元素的和。那么,任意区间[l,r]的元素和就可以表示为sum[r]-sum[l-1]。

二、前缀和算法的实现方法

前缀和算法的实现方法也很简单,只需要遍历一遍原数组,依次计算出每个位置的前缀和即可。具体来说,我们可以用以下代码实现:
int n; // 数组长度
int a[N]; // 原数组
int sum[N]; // 前缀和数组
// 计算前缀和
for (int i = 1; i <= n; i++) {
    sum[i] = sum[i-1] + a[i];
}

三、前缀和算法的应用场景

例1

题目描述:

给定一个长度为n的序列a1,a2,…,an,m个询问,每个询问包含两个整数l和r,求al,al+1,…,ar的和。

输入格式:

第一行包含两个整数n和m。
第二行包含n个整数,表示整个序列。
接下来m行,每行包含两个整数l和r,表示一个询问。

输出格式:

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

输入样例:

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

输出样例:

3
16
10

AC代码

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int a[N], s[N];
int main(){
    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;
}

例2

题目来源: https://www.luogu.com.cn/problem/AT2412

题目

读入n个整数的数列a1,a2,…,an和正整数k(1<=k<=n),请输出连续排列的k个整数的和的最大值

输入

第一行是正整数n(1<=n<=100000)和正整数k(1<=k<=n) 第二行以后的第1+i(1<=i<=n)至最后一行为数列

输出

仅一行,仅包括最大值(最后需要换行)。

样例输入

5 3
2 5 -4 10 3

样例输出

11

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, k;
int a[N], s[N],ans = -1000000000;
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    for(int i=k;i<=n;i++)
        ans=max(ans,s[i]-s[i-k]);
    cout<<ans<<endl;
    return 0;    
} 

例3

给定n个整数a[1],a[2],...,a[n],求两两相乘再相加的和,即
S=a[1]·a[2]+a[1]·a[3]+...+a[1]·a[n]+a[2]·a[3]+...+a[2]·a[n]+...+a[n-1]·a[n]

输入

第一行为正整数n,第二行为n个整数。
30%的数据:2≤n≤1000,1≤a[i]≤100。
100%的数据:2≤n≤200000,1≤a[i]≤1000。

输出

输出一个数字表示答案S。

输入

4
1 3 6 9

输出

117

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int main(){
    long long int n,sum=0,ans=0,a[N];
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        ans+=sum*a[i];
        sum+=a[i];
    }
    cout<<ans;
    return 0;
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值