#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, q;
cin >> n >> q;
vector<int> a(n + 1);
vector<int> diff(n + 2, 0); // 初始化差分数组
// 读取初始球数,构建差分数组
for (int i = 1; i <= n; ++i) {
cin >> a[i];
diff[i] += a[i] - (i == 1 ? 0 : a[i-1]);
}
// 处理每次操作
while (q--) {
int l, r, c;
cin >> l >> r >> c;
diff[l] += c;
if (r + 1 <= n) diff[r + 1] -= c;
}
// 根据差分数组还原最终数组
for (int i = 1; i <= n; ++i) {
diff[i] += diff[i - 1];
cout << diff[i] << (i == n ? '\n' : ' ');
}
return 0;
}
给定一个含有n个元素的数组,其中每个元素代表一个球筐中球的初始数量。接着,程序会接受q次更新操作,每次操作指定一个范围[l, r],以及一个值c,程序需要将这个范围内的每个球筐的球数增加c。最终程序输出在所有操作执行完成后,每个球筐中的球数量。
为了有效地实现这个功能,程序使用了差分数组技术。差分数组的主要优势是能在O(1)的时间复杂度内实现对原始数组某个区间内所有元素的同量增加或减少。
代码分析:
4. int main() {
5. int n, q;
main
函数是程序的入口点,定义了两个整数变量n
和q
,分别代表球筐的数量和操作的次数。
6. cin >> n >> q;
这行代码从标准输入读取这两个变量的值。
7. vector<int> a(n + 1);
8. vector<int> diff(n + 2, 0);
定义了两个整数类型的向量a
和diff
。a
用于存储每个球筐的初始球数。diff
是差分数组,其中每个元素初始化为0,其容量设置为n+2
,这样即使对于最后一个球筐进行操作时,也不会越界。
9. // 读取初始球数,构建差分数组
10. for (int i = 1; i <= n; ++i) {
11. cin >> a[i];
12. diff[i] += a[i] - (i == 1 ? 0 : a[i-1]);
13. }
这个循环读取初始的球数,并初始化差分数组diff
。对于差分数组而言,第一个元素就是原数组的第一个元素的值,后续元素diff[i]
代表a[i]
与a[i-1]
的差值。
14. // 处理每次操作
15. while (q--) {
16. int l, r, c;
17. cin >> l >> r >> c;
18. diff[l] += c;
19. if (r + 1 <= n) diff[r + 1] -= c;
20. }
这个循环处理每次更新操作。对于每次操作,我们只更新差分数组的l和r+1位置。这样做的效果是,在后续计算前缀和时,[l, r]
区间内的每个元素都会被正确地增加c
。
21. // 根据差分数组还原最终数组
22. for (int i = 1; i <= n; ++i) {
23. diff[i] += diff[i - 1];
24. cout << diff[i] << (i == n ? '\n' : ' ');
25. }
这个循环基于差分数组计算最终的球的数量(即还原数组a
),并将其打印出来。每个元素的值都是它自己加上前一个元素的值(这实际上是计算前缀和的过程)。
这段代码利用差分数组处理区间更新操作,无需对每个区间的元素逐一进行操作,从而将时间复杂度从O(q*n)降低到O(n+q)。