由于比赛基本都是采用Dev-C++所以,算法篇基本都是采用Dev-C++来解释(版本5.11,c++11)
首先介绍一下前缀和算法
给定一个数组,有q次询问,每次询问:
两个整数l,r,求出数组 l 到 r的结果
遇到问题首先先来分析问题
上图:
第一种方法,相信大家都会写,所以我们现在来写第二种解法:
数学中的求和公式,我们可以将其变为:
那我们为什么要这么做呢?
例如:上面的数组 1 2 3 4 5
用这个公式可以得出 1 3 6 10 15
得出的东西是什么呢?
可见,每一项就等于自身的值,加上前面的所有项的值
那我们应该如何求区间中的值呢?
数组[r]-数组[l-1]
要求蓝色的值,我们就要用从数组开始一直到 r 的值减去数组开始一直到 l-1 的值。
证明一下,比如我们要求 l =2,r=5
上面我们已经求得了数组开始一直加到数组结尾,值为15,数组[l-1]的值为1
最终我们所得的值为 14.
下来我们写一下代码:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e5+9;
void test()
{
int lenth,q;
cin>>lenth>>q;
ll arr[N],perfix[N];
for(int i=1;i<=lenth;i++)
{
cin>>arr[i];
}
for(int i=1;i<=lenth;i++)
{
perfix[i]=perfix[i-1]+arr[i];
}
while(q--)
{
int l,r;
cin>>l>>r;
cout<<perfix[r]-perfix[l-1]<<'\n';
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
test();
}
return 0;
}
代码没有问题,这里有一点我想提一下,这里的代码,数组arr[0]是不存东西的,是为了方便后面前缀和,有的小伙伴代码风格不同,就是要从0开始,也是可以的
通过调试:
我们可以看到时这样存储的,我们题目中询问l=2 r=5并不是问下标,而是实打实元素的顺序,要解决这一问题,我们可以
将perfix[i]=perfix[i-1]+arr[i];改为现在这样这样就妥了
当然还有别的修改办法,这里就不一 一列举了。