AcWing 797. 差分
原题链接
简单
作者:
Stack456
,
2021-04-24 22:55:03
,
所有人可见
,
阅读 2
差分理解记录过程
- 差分与前缀和是相逆的过程
- 有数组a满足以下条件: ai = b1 + b2 + b3 + b4 + ··· + bi; 即a的每一项都是有b的前i项构成,那么a就是b数组的前缀和,b数组就a的差分
- 构建过程 a1 = b1, a2 = b1 + b2 = a1 + b2,b2 = a2 - a1; 同理 ai = b1 + b2 + ··· + bi = (b1 + b2 + ··· + bi-1) + bi = ai-1 + bi 所以bi = ai - ai-1
差分使用,找事在l, r之间让a数组的每个数加上c
- 那么al = b1 + b2 + … + bl-1 + bl + c
- a(l + 1) = b1 + b2 + … + bl + b(l+1) = al + b(l+1),因为此时al的数值更新过过得,所以a(l+1)会比之前的结果多了一个c, 那么从l一直到结尾都是+c的,只要继续球就是的
- 如果是知识点l到r之间的话,那么从r+1起,就不能多c
- 而 a(r+1) = ar + b(r+1),此时是多的,所以需要减掉-c
- 那么插入过程就是b[l] + c, b[r+1] - c,
- 越界问题,如果数组r是最后一个的元素的话,那么b[r+1] - c,不久越界了吗,范围不是多计算了,其实不然,因为a数组都到了最后,没有下一个元素,此时的题目就相当于从l开始一直加到末尾即可
差分使用的初始化问题
- a数组本来就有数组,如何求解差分b数组呢
- 假设a数组全部为0,b数组也就是全部为零了,如果a1有数值的话,因为a1 = b1, 所以就是相当于在之前的b数组中从1 - 1 插入了元素a1的值,如a2,就是原来的b数组中多了一个a2的数值啊,直接[2,2,a2]插入即可
- 同理,插入过程就是从1 到 n 每次都是同位置插入了 a, 所以直接插入就行
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int a[N], b[N];
void insert(int l, int r, int c)
{
b[l] += c;
b[r + 1] -= c;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++ ) insert(i, i, a[i]); //构建b数组
while (m --)
{
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
insert(l, r, c); //进行求和
}
for(int i = 1; i <= n; i ++) b[i] += b[i-1];
for(int i = 1;i <= n; i ++ ) printf("%d ", b[i]);
return 0;
}