题目:求区间和
题号:B3612
难度:普及一
题目分析
从题目分析上是个特别简单的题,但是身为普及题肯定有它的道理
一般人看到这道题的基本思路
1:首先输入n 然后循环输入读取n个数的数列,并且储存在数组中。
2:输入m循环输入储存m个区间在一个或两个数组中。
3:通过循环依次遍历每个区间求和并且分别换行输出。
但是从下图可知
区间数量甚至可以有接近十万个,而且数列可以有进一万的长度,这样算下来,最多可以遍历进十亿次,显然这超出了一般的时间规定,该方法时间复杂度为 O(m*n),肯定是超时了
解决办法
既然如此,我们不妨换个思路,既然所需要求的是区间的和,
如果初始数组中储存的不是每个数,而是a[n] = a[n-1] + s,也就是储存前n项的和
这样的话,如果需要[x,y]的和,只需要a[y] - a[x-1]即可,而不需要重新遍历区间。
这样时间复杂度也从 O(m*n)变成了O(m+n),所费时间大幅降低,话不多说,上代码。
#include<stdio.h>
int n,m,i,i1,i2,c,q,p;
int main()
{
scanf("%d",&n);
int a[n+1];
a[0]=0;
for(i=1;i<=n;i++)
{ scanf("%d",&c);
a[i]=a[i-1]+c; }
scanf("%d",&m);
int L[m+1];
for(i2=1;i2<=m;i2++)
{ scanf("%d %d",&q,&p);
int num=a[p]-a[q-1];
L[i2]=num; }
for(i1=1;i1<=m;i1++)
printf("%d\n",L[i1]);
return 0;
}
改进点:
1. 预处理前缀和数组sum,sum[i]表示前i项的和
2. 每个查询直接通过sum[R]-sum[L-1]得到结果
3. 减少了循环层数,提升了处理速度
4. 使用局部变量,代码更清晰
总体思想:
1. 读取数据并构建前缀和数组:读入 n 和数列 a ,构建前缀和数组 sum ,其中 sum[i] 表示前 i 项的和,即 sum[i] = sum[i-1] + a[i] 。
2. 处理查询:对每个区间 [L, R] ,利用前缀和计算和为 sum[R] - sum[L-1] 。