D - 一维前缀和
题目
一天,在宿舍睡觉的你,突然梦到了游戏之神,他说:去玩《极限脱出》吧,这部作品的剧情和世界观绝对会带来很大的震撼,值得一玩。
对了,这部作品的第一代发布在nds上,所以要想在电脑上玩,你需要游戏模拟器:推荐desmume,也可以选择nogba,前者虽然优化差一些,但自带了模拟器的即使存档功能,且可以全屏。
但由于你没有吃安利,游戏之神很愤怒(这么好的游戏不玩,暴殄天物啊!),决定对你进行惩罚。
现在,游戏之神给了你n个非负整数,分别记为第1个数字至第n个数字,游戏之神还会向你提出q个问题,询问你第f个数到第t个数之间所有数字的和,请你正确回答游戏之神的所有提问,否则你以后打游戏必掉线。
Input
输入的第一行包含两个整数n,q( 1≤n,q≤10^5 ),含义如题面所示;
第二行包含n个非负整数,每个数字均不超过10^9;
下面q行,每行包括两个数字f,t(1≤f≤t≤n),含义如题面所示。
Output
对于这q行中的每一行,请你输出一个数字,回答游戏之神的提问。
Example
Input
9 4 1 3 4 6 2 5 1000000000 1000000000 1000000000 1 6 7 9 3 5 4 4
Output
21 3000000000 12 6
思路
观察题目中的提问次数,如果要暴力来做的话,最坏的时间复杂度是O(n²),按10^5来算时间已经爆了,所以我们要用前缀和来减少计算的次数,输入的时候只需预处理一下就好了。
例如:
原数组为
当每次输入的时候都把该元素前面的元素加起来,a[n]+=a[n-1]
这样我们预处理后的得到数组应该是
当题目求数组下标为 f 到 t 之间的元素之和的时候,我们只需输出a[f]-a[t-1]即可
如从a数组第二个元素加到第六个元素之和 = a[6]-a[2 - 1],即2 + 3 + 4 + 5 + 6 = 21 - 1 = 20
代码
#include<iostream>
using namespace std;
long long n, q, a[100005], f, t;//注意该题要用longlong,否则会爆
int main()
{
cin >> n >> q;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
a[i] += a[i - 1];
}
while (q--)
{
cin >> f >> t;
cout << a[t] - a[f - 1] << endl;
}
return 0;
}