B3612 【深进1.例1】求区间和
题目描述
给定 个正整数组成的数列 和 个区间 ,分别求这 个区间的区间和。
输入格式
第一行,为一个正整数 。
第二行,为 个正整数
第三行,为一个正整数 。
接下来 行,每行为两个正整数 ,满足
输出格式
共 行。
第 行为第 组答案的询问。
输入输出样例 #1
输入 #1
4
4 3 2 1
2
1 4
2 3
输出 #1
10
5
说明/提示
样例解释:第 1 到第 4 个数加起来和为 10。第 2 个数到第 3 个数加起来和为 5。
对于 的数据: ;
对于 的数据:,。
思路
使用前缀和来高效计算区间和。前缀和是一种预处理技术,通过预先计算数组的前缀和,可以在 O(1)O(1) 的时间内查询任意区间的和。
具体步骤如下:
-
计算前缀和数组:
- 定义数组
sum
,其中sum[i]
表示数组 aa 的前 ii 个元素的和。 - 递推公式:
sum[i] = sum[i-1] + a[i-1]
。
- 定义数组
-
查询区间和:
- 对于每个查询 [li,ri][li,ri],区间和可以通过前缀和数组快速计算:区间和=sum[ri]−sum[li−1]区间和=sum[ri]−sum[li−1]
代码实现
java
复制代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取数组长度 n
int n = sc.nextInt();
// 读取数组 a
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
// 计算前缀和数组 sum
long[] sum = new long[n + 1];
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + a[i - 1];
}
// 读取查询数量 m
int m = sc.nextInt();
// 处理每个查询
long[] res = new long[m];
for (int i = 0; i < m; i++) {
int l = sc.nextInt();
int r = sc.nextInt();
res[i] = sum[r] - sum[l - 1];
}
// 输出结果
for (long s : res) {
System.out.println(s);
}
}
}
显示更多
代码解释
-
输入处理:
- 读取数组长度 nn。
- 读取数组 aa 并存储。
- 计算前缀和数组
sum
,其中sum[i]
表示数组 aa 的前 ii 个元素的和。
-
查询处理:
- 读取查询数量 mm。
- 对于每个查询 [li,ri][li,ri],通过前缀和数组快速计算区间和,并存储结果。
-
输出结果:
- 遍历结果数组
res
,输出每个查询的结果。
- 遍历结果数组
复杂度分析
-
时间复杂度:
- 计算前缀和数组:O(n)O(n)。
- 处理 mm 个查询:O(m)O(m)。
- 总时间复杂度:O(n+m)O(n+m)。
-
空间复杂度:
- 前缀和数组
sum
占用 O(n)O(n) 空间。 - 结果数组
res
占用 O(m)O(m) 空间。 - 总空间复杂度:O(n+m)O(n+m)。
- 前缀和数组