#C03L04P01. C03.L04.前缀和入门.概念
C03.L04.前缀和入门.概念
在讲算法之前,我们先来思考一个问题:小明有n个编号为1~n的篮子,每个篮子里装有ai个苹果,求从 x至y 的篮子里的苹果数量之和。
如果没学过前缀和的同学,可能会打出这样的代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,x,y,l[101],ans=0,i;
cin>>n>>x>>y;
for(i=1;i<=n;i++)
{
cin>>l[i];
if(i>=x&&i<=y)
ans += l[i];
}
cout<<ans;
return 0;
}
这种算法要得出一个区间之和,这题只需要取一次区间值,时间复杂度需要 O(n),但如果 2 次,4 次,1000 次,数据再一大,暴力算法肯定会超时的,这时,前缀和的优势就体现出来了,因为它取区间之和,只需要 O(1)。
那前缀和的思想是什么呢?又是如何实现用 O(1) 取区间之和的呢?其思想就是遍历 1 至 n ,算出 1 至当前数字的区间之和,有人或许会问了,那这样也无法算出特定区间之和啊,但我们观察后发现,在累加数组,前缀为右顶点的数字包含了前缀为左顶点的数字,通过用累加数组中的右顶点减去总顶点,再加上初始数组前缀为左顶点的值,可以得到:求 x 至 y 区间之和为:s[y]-s[x-1](s为累加数组)
(一)前缀和算法
前缀和的基本代码:
概念:前缀和就是数组的前 i 项之和
一维前缀和
记原数组为a[n],前缀和数组为 s[n] 。那么 s[i] 内存储的内容为 a[1] ~ a[i-1] 的和。
b[1] = a[1];
b[2] = a[1] + a[2];
b[3] = a[1] + a[2] + a[3];
b[4] = a[1] + a[2] + a[3] + a[4];
b[5] = a[1] + a[2] + a[3] + a[4] + a[5];
因此,结合for循环,前缀和的基本代码是:
b[0] = 0; //当b数组为全局变量数组是,此句可以省略
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i] = a[i] + b[i-1];
}
//求从第x项目到第y项之和
cout<<b[y]-b[x-1];
知识与要点
前缀和不一定是和,也可以是前缀积......
前缀和是一种预处理算法,能大大降低时间复杂度,特别适合于很多次查询(问题)的情况。
前缀和的操作对象主要是数组。
前缀和主要是计算之前数组元素的值之和。在解决区域问题时,可以减少遍历操作,减少时间复杂度。
相关
在以下作业中: