Original: Original link
Similar to derivation and integration in mathematics, the difference can be看成前缀和的逆运算。
Difference array:
First, give an original array a: a[1], a[2], a[3], a[n];
Then we construct an array b: b[1] ,b[2], b[3], b[i];
Use a [i] = b [1] + b [2] + b [3] +, + b [i]
In other words, array a is the prefix and array of array b, and in turn we call array b the difference array of array a. In other words, each a[i] is a sum of intervals from the beginning in the b array.
Consider how to construct a differential b array?
The most direct method
as follows:
a[0 ]= 0;
b[1] = a[1] - a[0];
b[2] = a[2] - a[1];
b[3] =a [3] - a[2];
…
b[n] = a[n] - a[n-1];
Icon:
As long as we have the b array, through the prefix and operation, we can get the a array in O(n) time.
What is the use of knowing the difference array? Don't worry, look down slowly.
There is such a problem:
Given the interval [l ,r], let us add c to every number in the interval [l, r] in the a array, that is, a[l] + c, a[l+1] + c, a [l+2] + c, a[r] + c;
The brute force method is the for loop between l and r, and the time complexity is O(n). If we need to perform such operations on the original array m times, the time complexity will become O(n*m). Is there a more efficient approach? Consider the difference approach.
Always remember that the a array is the prefix and array of the b array. For example, the modification of b[i] in the b array will affect every number in the a array from a[i] and beyond.
First, let b[l] + c in the difference b array, and the a array become a[l] + c, a[l+1] + c, a[n] + c;
Then we apply a patch, b[r+1]-c, a array becomes a[r+1]-c,a[r+2]-c,a[n]-c;
Why do we need a patch?
Let's draw a picture to understand the origin of this formula:
b[l] + c, the effect is that c (red part) is added to the a[l] and subsequent numbers in the a array, but we only require the range from l to r to add c, so we also need to execute b[r+ 1]-c, subtract c (the green part) from a[r+1] and the subsequent intervals in the a array, so that the number of intervals after a[r] is equivalent to no change.
Therefore, we come to the conclusion of one-dimensional difference: add c to every number in the interval [l, r] in the a array, and just do b[l] + = c, b[r+1 for the difference array b ]-= c. The time complexity is O(1), which greatly improves efficiency.
to sum up:
Summary of personal experience of prefix sum and difference
AC code
//差分 时间复杂度 o(m)
#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]; //构建差分数组
}
int l, r, c;
while (m--)
{
scanf("%d%d%d", &l, &r, &c);
b[l] += c; //将序列中[l, r]之间的每个数都加上c
b[r + 1] -= c;
}
for (int i = 1; i <= n; i++)
{
a[i] = b[i] + a[i - 1]; //前缀和运算
printf("%d ", a[i]);
}
return 0;
}