让求某一区间的和,那么前缀和也同样能够完成,但是如果操作的次数过大
那么前缀和显然会超时,但是同样有解决的方式例如 树状数组,线段树。
顾名思义, `
- sum[i] = a[i] - a[i - 1];`
- sum[l] += val; sum[r + 1] -= val; (这里取决于具体情况,但一般是这个) (我记得有个图, 找不到了)
----------------------------------------------------
^ ^
| |
l r
sum[l] + val------------------------------------------
(这里我只需要[l, r],但是发现多加了)
sum[r] - val --------------------
(所以需要减去加的那个值)
因为sum[]是前缀和,对区间进行的操作
-a[i] = sum[i] + a[i - 1]; 这就是改变后的值
核心:
- 从1开始 (从0开始的话,第一个的前缀和就没法求)
- 注意a[i] = a[i - 1] + sum[i - 1] 这里的a[i]是能影响上一步的
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 1e5;
int a[maxn];
int sum[maxn];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i){
cin >> a[i];
sum[i] = a[i] - a[i - 1];
}
int l, r, c;
for (int i = 1; i <= m; ++i){
cin >> l >> r >> c;
sum[l] += c;
sum[r + 1] -= c;
}
for (int i = 1; i <= n; ++i){
a[i] = sum[i] + a[i - 1];
// if (i == 1)
// cout << (sum[i] + a[i - 1]);
// else cout << " " << (sum[i] + a[i - 1]);
//这样是错误的, 前面 a[i - 1] 会影响到后续的计算
if (i == 1)
cout << a[i];
else cout << " " << a[i];
}
cout << endl;
return 0;
}