1.前文
嗯对,在昨天作者写了一些无脑的玩意,大家就当个乐子看。
(顺便放一下网址)
2.正文
2.1前缀和的介绍
讲一个小故事,虽然纯属虚构:
从前有一个程序员,他想求多个从第个数到第
个数的总和。
(假设下面的变量代表的数字全都不超过)
他首先就想到要输入个数,再输入
,代表要测几次。
再分别输入和
,用一个变量
求从第
个数到第
个数的总和。
代码大致是这样的:
cpp
#include<bits/stdc++.h>
using namespace std;
int a[10005];
int main()
{
int n,m;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
cin>>m;
for(int i=1;i<=m;i++)
{
int sum=0,x,y;
cin>>x>>y;
for(int j=x;j<=y;j++)
{
sum+=a[j];
}
cout<<sum<<endl;
}
return 0;
}
听起来很简单,但他发现如果评测机一秒钟测试上限是,
和
等于或接近
时,时间就会超过一秒钟。
为此,他想破脑袋才想出来了一个绝妙的方法------前缀和。
2.2前缀和的代码
他告诉你前缀和是怎么运作的:
假设有一个数组,里面的元素是这样的:
1、3、5、7、9。
让你求第二个到第四个的和。
正常人都会一个个加。可前缀和不是这样。
它在输入数组的时候就开始了。
cpp
#include<bits/stdc++.h>
using namespace std;
int a[10005];
int s[10005];
int main()
{
int n,m;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
}
return 0;
}
此时数组(前缀和数组)里面的值是:
1、4、9、16、25。
求第二个数到第四个数的和就是
cpp
s[4]-s[1];
你可能会问,为什么要减1而不是
2呢?
他又说:"看看数组里的数!"
一个个加的做法:
3+5+7=15。
前缀和的做法:
16-1=15。
这可快多了!
这个程序员又把下面代码放到评测机里测试:
cpp
#include<bits/stdc++.h>
using namespace std;
int a[10005];
int s[10005];
int main()
{
int n,m;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
}
cin>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
cout<<s[x]-s[y-1]<<endl;
}
return 0;
}
我去!什么时间超限?不是秒了吗!
至此,故事结束。
(逃!)
新手小白(提高A)