开讲之前,先讲点题外话,(之前的文章都太差,好像还没人看过)这一次,我会教点干货给大家
现在进入正题,今日份主题——前缀和
目录
先问大家一个问题,什么是前缀和?
前缀和优点
来看这一个问题
小明有n个编号为1~n的篮子,每个篮子装有ai个苹果,求从x至y的篮子里的苹果数。
可能有人是这么打
(学过例外)
but这种方法的时间复杂度是O(n),当n一大就肯定TLE
so这种时候就需要前缀和来帮忙了,because他的时间复杂度才O(1)。
(就问你羡不羡慕)
前缀和思想
简单来说就是数组下标1至下标当前数字之和
如图(s为累加列表):
前缀和实现
回到上面的问题,求a[x]-a[y]之间的和,s[x]=a[1]+a[2]+……a[x],s[y-1]=a[1]+a[2]+……+a[y-1],所以a[x]-a[y]之间的和=s[x]-s[y-1]=a[1]+a[2]+……+a[x]-a[1]-a[2]-……a[y-1](应该推导过程不用说了吧,
傻子都懂)基本代码为:
前缀和应用
例题:
前缀和
题目描述
有N个的正整数放到数组A里,现在要求一个新的数组B,新数组的第i个数B[i]是原数组A第0到第i个数的和。
A数组前面一段数的和称为“前缀和”,“前缀和数组”B在很多算法中很有用。输入格式
第一行1个正整数:N,N范围在[1,100]。
第二行N个正整数:范围在[1,10000]。输出格式
N正整数。
输入/输出例子1
输入:
6
2 6 1 9 7 3输出:
2 8 9 18 25 28
#include<bits/stdc++.h>
using namespace std;
int n,a[1005],ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ans+=a[i];
cout<<ans<<" ";
}
return 0;
}
(异常想不到的短,但这的确运用了很典型的前缀和算法)
最后总结
前缀和可以灵活变动,前缀积,前缀减,前缀除……只有你想不到没有你做不到!
但它也是一种预处理算法,可以大大降低时间复杂度。
到了末尾,很感谢读者看到这里。下周六,我会讲二维前缀和(补补前缀和的小尾巴),我们不见不散——