文章目录
795.前缀和
题目描述
输入一个长度为n的整数序列。
接下来再输入m个询问,每个询问输入一对l, r。
对于每个询问,输出原序列中从第l个数到第r个数的和。
输入格式
第一行包含两个整数n和m。
第二行包含n个整数,表示整数数列。
接下来m行,每行包含两个整数l和r,表示一个询问的区间范围。
输出格式
共m行,每行输出一个询问的结果。
数据范围
1≤l≤r≤n,
1≤n,m≤100000,
-1000≤数列中元素的值≤1000
输入样例:
5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10
前缀和
这段代码是用来解决前缀和问题的,用于快速计算区间内所有数的和。下面是详细注释:
cpp
#include<bits/stdc++.h> // 包含大部分常用的库
using namespace std;
const int z=100010; // 定义常量z为100010,作为数组大小的上限
int a[z],s[z]; // a是输入的数列,s是前缀和数组
int main() {
int n,m,i; // n是数列的长度,m是查询的次数,i是循环变量
scanf("%d %d",&n,&m); // 读入n和m
for(i=1;i<=n;i++)
scanf("%d",&a[i]); // 读入数列,存入a数组
for(i=1;i<=n;i++)
s[i]=s[i-1]+a[i]; // 计算前缀和,s[i]存的是a[1]到a[i]的和
while(m--) // 循环m次,对每个查询进行处理
{
int l,r;
scanf("%d %d",&l,&r); // 读入查询的区间[l, r]
printf("%d\n",s[r]-s[l-1]); // 输出区间和,即s[r]减去s[l-1]的值
}
return 0;
}
这段代码的核心是前缀和的概念。前缀和是一个非常有用的工具,特别是当我们需要频繁地查询某个区间内的元素和时。
前缀和数组s是这样定义的:s[i]表示从a[1]到a[i]的元素和。这意味着,为了得到任意区间[l,r]的和,我们可以用s[r](包含从a[1]到a[r]的所有元素的和)减去s[l-1](包含从a[1]到a[l-1]的所有元素的和)。这样就可以在O(1)的时间内得到任意区间的和,而不必每次询问都遍历整个区间,这在处理大量数据时非常有效率。
注意:本代码中的数组从索引1开始,而不是通常的从索引0开始,因此当计算前缀和时,s[0]默认为0。这也是为什么在计算区间和时使用s[r]-s[l-1]而不是s[r]-s[l]。如果l为1,s[l-1]为s[0],表示没有元素的和,即为0。