差分(前缀和的逆运算)
#include<iostream> using namespace std; const int N = 1e5 + 10; int a[N], b[N]; int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = a[i] - a[i - 1]; //构建差分数组 } //上面是构建差分数组, // b[1]=a[1]-a[0] // b[2]=a[2]-a[1] // b[3]=a[3]-a[2] // ········· // b[6]=a[6]-a[5]; //目的是为了在前缀和中通过b里的某个元素修改后去修改a后面的值 //构造了差分数组后就已经有了比如a[3]=b[3]+b[2]+b[1];这种前缀和关系。 //只不过现在不用,因为为了去修改a的值我们还需要对中间的b进行修改,所以接下来 //是先对b修改,再调用a[3]=b[3]+b[2]+b[1]; int l, r, c; while (m--) { scanf("%d%d%d", &l, &r, &c); b[l] += c; //将序列中[l, r]之间的每个数都加上c b[r + 1] -= c; } //调用a[3]=b[3]+b[2]+b[1];这种前缀和运算。 for (int i = 1; i <= n; i++) { a[i] = b[i] + a[i - 1]; //前缀和运算 printf("%d ", a[i]); } //前缀和运算a[3]=b[3]+b[2]+b[1] 因为前面已经构造了差分数组所以此时一定是成立的 //而且如果 中间的某个b不变的话那么a 就不会变。 // a[3]=b[3]+b[2]+b[1] //a[4]=b[4]+b[3]+b[2]+b[1] //他们可以直接写成这个样子 //那么对中间的b[3] 修改了就是对a[3] 之后的值都修改了 //这种。 return 0; }