1.问题
输入一个长度为 n 的整数序列。
接下来再输入 m 个询问,每个询问输入一对 l,r。
对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
输入格式
第一行包含两个整数 n 和 m。
第二行包含 n 个整数,表示整数数列。
接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。
输出格式
共 m行,每行输出一个询问的结果。
数据范围
1≤l≤r≤n1≤𝑙≤𝑟≤𝑛,
1≤n,m≤1000001≤𝑛,𝑚≤100000,
−1000≤数列中元素的值≤1000
输入样例:
5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10
2.思路
思路1:每次求l,r的和,我们从下标l开始循环到下标r结束,把循环过程中的值加起来;
下标l开始循环到下标r的循环次数最多n,我们又要进行m组询问,所以
时间复杂度:O(n*m)
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//数组的长度
int n = sc.nextInt();
//询问的次数
int m = sc.nextInt();
//存储的输入的数组
int[]a = new int[1000010];
//输入n个数
for(int i=1;i<=n;i++){
a[i]=sc.nextInt();
}
//循环m次,输入l,r
for(int i=1;i<=m;i++){
int l = sc.nextInt();
int r = sc.nextInt();
//存储累加结果
int sum = 0;
//从l开始遍历到r,累加a[j]
for(int j=l;j<=r;j++){
sum+=a[j];
}
//输出这次询问的结果
System.out.println(sum);
}
}
}
思路2:如果我们知道从 [1,l-1]的和 以及 [1,r]的和,[1,r]的和 减去 [1,l-1]的和,不就能不循环就得到每组[l,r]区间的和吗?
那么我们如何得出[1 , l-1]和[1 , r]的和呢?
我们将问题一般化,我们要得出的是 [1,i]的和 ,i>=1
我们可以用一个数组sum[i]表示 [1,i]的和,我们找规律,不难发现sum[i]=sum[i-1]+a[i];
也就是从1到i的和 等于 从1到i-1的和 加上 数组当前第i个数a[i]
所以我们只需遍历数组a,就可以得到sum[i]了。
遍历数组a的时间复杂度在O(n),对于m次询问得到sum[r]-sum[l-1]的时间复杂度是O(m),
所以最终时间复杂度在O(Max(n,m))
代码
//存储的输入的数组
int[]a = new int[1000010];
//sum[i]表示 [1,i]的和
int[]sum = new int[1000010];
//循环输入数据a[i],并得到sum[i]
for(int i=1;i<=n;i++){
a[i]=sc.nextInt();
sum[i]=sum[i-1]+a[i];
}
//循环m次,输入l,r
for(int i=1;i<=m;i++){
//求和区间的左端点下标
int l = sc.nextInt();
//求和区间的左端点下标
int r = sc.nextInt();
//输出这次询问的结果 从[1,r]的和减去从[1,l-1]的和得到[l,r]的和
System.out.println(sum[r]-sum[l-1]);
}
}
}