y总原样模板+注释理解
#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int a[N], b[N]; //a数组是b数组的前缀和,b数组是a数组的差分
void insert(int l, int r, int c) //定义insert函数,左右边界l,r 和需要插入的值c
{
//因为a数组是b数组的前缀和
//所以只需要对b[l],b[r + 1]这两个值进行+c,-c的操作,即可实现a数组的[l,r]之间的每个数加上 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]); //读入a数组
//假定a数组最开始都是0,那么b数组初始时就是a数组的差分数组了
//对于每一个已经读入并存好的a[i],可以看成是操纵b数组 实现 在a数组的(i,i)处插入a[i]这单个值得到的
//此时,左右边界是i,值是a[i],可以直接利用insert函数
//调用insert函数的目的不是为了操纵/计算a数组(因为a数组是读入的,规定好的)
//而是用 “看成是操纵b数组 实现 在a数组的(i,i)处插入a[i]这单个值得到的”这个思想
//反过来计算b数组的值并存在b数组里
//insert函数中的b[l] += c 和 b[r + 1] -= c 可以做到(算和存)
//当然也可以从差分数组的定义出发,用显式的方法计算b数组
//for(int i=1;i<=n;i) b[i]=a[i]-a[i-1] 这就是差分公式
//效果一样
for (int i = 1; i <= n; i ++ ) insert(i, i, a[i]);
//此时已经读入了a数组 并且 利用a数组反求了b数组
while (m -- )
{
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
//执行题目的要求,在a数组的[l,r]之间的每个数加上 c,即调用insert函数
//但是注意!!!实际上你修改的是b数组的值,a数组只是在“意义上”在[l,r]之间的每个数加上 c
//因为你的思想是 “通过对b[l],b[r + 1]这两个值进行+c,-c的操作,实现a数组的[l,r]之间的每个数加上 c”
//实际上目前a数组里存的值,你并没有改动,还是之前读入进来的样子
//所以在这之后,需要累加b数组的值,求出修改后的a数组,然后输出
insert(l, r, c);
}
//由于b数组是a数组的差分(b1=a1, b2=a2-a1, b3=a3=a2)
//所以从1开始累加b数组,也就是b[i] = b[i] + b[i - 1],这样可以相互抵消
//得到的结果是:每一个b[i]==a[i],从而打印累加后的b数组,就是答案
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;
}