[Acwing Algorithm Foundation] 2.6 Difference

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;
}

Guess you like

Origin blog.csdn.net/qq_22473333/article/details/114988343
Recommended