前缀和算法是一种常用的算法,它可以用来快速计算一个数组中某个区间内的元素和。在本文中,我们将介绍前缀和算法的原理、实现方法以及应用例子。
一、前缀和算法的原理
前缀和算法的原理很简单,就是先计算出数组的前缀和,然后通过前缀和的差值来计算出任意区间的元素和。具体来说,我们可以用一个数组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;
}