#include<iostream> #include<vector> using namespace std; int main(){ int n; int a,b; cin>>n; int sum; vector<int> Array(n); vector<int> p(n); p[0]=0; for(int i=0;i<n;i++){ cin>>Array[i]; p[i]+=Array[i]; } while (cin >> a >> b) { if (a == 0) sum = p[b]; else sum = p[b] - p[a - 1]; cout << sum << endl; } }
时间: 2025-04-03 11:12:05 浏览: 50
这是一个经典的“前缀和”算法程序,用于高效解决区间求和的问题。下面是对该代码的功能、逻辑以及关键点的详细解析:
---
### 程序功能:
这个程序的主要目的是计算给定数组 `Array` 中任意区间的元素之和,并通过预处理的方式提升效率。
#### 输入描述:
1. 首先输入整数 `n`,表示数组长度。
2. 接着输入 `n` 个整数值存入数组 `Array`。
3. 再从标准输入读取两个整数 `a` 和 `b`,表示查询范围 `[a, b]` 的区间和。
4. 如果 `a == 0`,则返回整个数组到索引 `b` 的累积值;如果 `a > 0`,则返回的是区间 `[a, b]` 的累计和。
#### 输出结果:
对于每个查询 `(a, b)`,输出对应的区间和并换行。
---
### 核心思想——前缀和:
为了快速响应多次区间查询需求而不每次都对指定区域重新遍历累加,我们使用了**前缀和**技术。
定义一个辅助数组 `p[]` 来存储前缀和信息:
- 设 `p[k] = Array[0] + Array[1] + ... + Array[k]`
- 对于任意区间 `[a, b]` 的和可以由公式得到:`sum(a, b) = p[b] - p[a-1]`
注意特殊情况:
- 当 `a == 0` 时,直接返回 `p[b]` 即可(因为不存在更早的部分需要减去)。
---
### 关键步骤解析:
1. **初始化变量及容器**
```cpp
vector<int> Array(n); // 存储原始数据
vector<int> p(n); // 前缀和数组,默认初始为全零
```
2. **构建前缀和表**
使用循环依次填充数组的同时更新前缀和:
```cpp
for(int i=0;i<n;i++) {
cin >> Array[i];
if(i > 0){
p[i] += p[i-1] + Array[i];
}
else{
p[i] += Array[i];
}
}
```
此处保证每次将当前值加入之前的所有累计总和之中形成新的前缀项。
3. **接收查询指令并打印答案**
进入无限循环等待用户进一步输入查询坐标直到结束为止:
```cpp
while(cin >> a >> b){
if(a == 0)
sum = p[b];
else
sum = p[b]-p[a-1];
cout << sum << endl;
}
```
---
### 示例运行过程:
假设输入如下内容:
```
5
1 2 3 4 5
1 3
0 4
2 4
```
解释每一步骤的结果:
- 数组 `Array=[1,2,3,4,5]`
- 构建出前缀和序列 `P=[1,3,6,10,15]`
随后按顺序给出三组询问的答案分别为:
- 查询 [1,3]: 结果等于 P[3]-P[0]=9−1=8 → 打印 "8"
- 查询 [0,4]: 直接获取 P[4]=15 → 打印 "15"
- 查询 [2,4]: 计算 P[4]-P[1]=15−3=12→ 打印 "12"
最终完整显示出来的应该是这样的形式:
```
8
15
12
```
---
### 总结优缺点
优点:借助预先生成好的前缀和结构大幅减少了反复扫描所需时间复杂度降至O(1),非常适合高频次随机访问场景下的优化方案设计思路体现得淋漓尽致!
需要注意的地方在于边界条件检查还有防止溢出等问题上做适当调整即可满足更多实际应用场合要求。
阅读全文
相关推荐



















