题解:洛谷 P8218 求区间和
【题目来源】
【题目描述】
给定 \(n\) 个正整数组成的数列 \(a_1, a_2, \cdots, a_n\) 和 \(m\) 个区间 \([l_i,r_i]\),分别求这 \(m\) 个区间的区间和。
对于所有测试数据,\(n,m\le10^5,a_i\le 10^4\)
【输入】
第一行,为一个正整数 \(n\)。
第二行,为 \(n\) 个正整数 \(a_1,a_2, \cdots ,a_n\)
第三行,为一个正整数 \(m\)。
接下来 \(m\) 行,每行为两个正整数 \(l_i,r_i\) ,满足\(1\le l_i\le r_i\le n\)
【输出】
共 \(m\) 行。
第 \(i\) 行为第 \(i\) 组答案的询问。
【输入样例】
4
4 3 2 1
2
1 4
2 3
【输出样例】
10
5
【核心思想】
-
问题分析:给定长度为 \(n\) 的正整数序列 \(a_1, a_2, \dots, a_n\),以及 \(m\) 个区间查询 \([l_i, r_i]\),需要依次输出每个区间内所有元素之和。由于 \(n, m \le 10^5\),若每次暴力求和会超时,需利用预处理将区间和查询优化为 \(O(1)\) 操作。
-
算法选择:
- 前缀和:预处理前缀和数组 \(S[i] = \sum_{k=1}^{i} a_k\)(\(1 \le i \le n\)),则区间 \([l, r]\) 的和为 \(S[r] - S[l-1]\)。预处理 \(O(n)\),每次查询 \(O(1)\),总时间复杂度 \(O(n+m)\),空间复杂度 \(O(n)\)。
-
关键步骤:
- 读入 \(n\) 和数组 \(a[1..n]\)。
- 计算前缀和数组 \(s[0] = 0\),对于 \(i=1..n\),\(s[i] = s[i-1] + a[i]\)。
- 读入 \(m\),对每个查询 \((l, r)\),输出 \(s[r] - s[l-1]\)。
-
时间/空间复杂度:
- 时间复杂度:\(O(n + m)\),预处理 \(O(n)\),每次查询 \(O(1)\)。
- 空间复杂度:\(O(n)\),存储前缀和数组。
-
前缀和的核心思想:
- 通过预计算前缀和,将子数组求和问题转化为两个前缀和的差,消除重复计算。
- 适用于静态数组的多次区间和查询,是处理区间统计问题的基础技巧。
- 可推广到二维前缀和、差分数组等更复杂的场景。
【算法标签】
普及- #前缀和
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 100005; // 定义数组最大长度
int n, m; // n: 数组长度, m: 查询次数
int a[MAX_N]; // 存储原始数组
int s[MAX_N]; // 存储前缀和数组
int main()
{
// 输入数组长度
cin >> n;
// 输入数组元素并计算前缀和
for (int i = 1; i <= n; i++)
{
cin >> a[i];
s[i] = s[i - 1] + a[i]; // 前缀和公式:s[i] = s[i-1] + a[i]
}
// 输入查询次数
cin >> m;
// 处理每个查询
for (int i = 1; i <= m; i++)
{
int l, r; // 查询区间[l, r]
cin >> l >> r;
// 输出区间和:s[r] - s[l-1]
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
// 使用acwing模板二刷
#include <bits/stdc++.h>
using namespace std;
const int N = 100005; // 定义数组最大长度
int n, m; // n: 数组长度, m: 查询次数
int a[N]; // 原始数组
int s[N]; // 前缀和数组
int main()
{
// 输入数组长度
cin >> n;
// 输入数组元素
for (int i = 1; i <= n; i++)
cin >> a[i];
// 计算前缀和数组
for (int i = 1; i <= n; i++)
s[i] = s[i - 1] + a[i]; // s[i] = 前i项的和
// 输入查询次数
cin >> m;
// 处理每个查询
while (m--)
{
int l, r; // 查询区间[l, r]
cin >> l >> r;
// 输出区间和:s[r] - s[l-1]
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
【运行结果】
4
4 3 2 1
2
1 4
10
2 3
5
浙公网安备 33010602011771号