Prefix sum and difference---concept + examples

Table of contents

prefix and

concept

example

difference

concept

example


prefix and


concept

I learned the concept of series in high school, which is very similar to the current array. By analogy, the prefix sum of the array and the sum of the first n items of the array can actually be regarded as a concept. Many algorithm problems use the idea of ​​prefix sum, that is, the sum of the first n items in high school can be used to solve the sum of elements in any interval in the array. Its formula is:

S{_n} = S{_{n - 1}} + a{_n}

Combined with practical examples: Suppose now there is an array arr:

arr = {1,2,3,4,5};

We now need to find the size Sum of the elements in the array whose subscript interval is [i, j], the calculation formula is:

Sum = S{_j} - S{_{j - 1}}

Note: Array subscripts are counted from 0.

In terms of specific steps, the operation method of the prefix sum is mainly divided into the following steps:

  • Preprocessing: first find the sum of the array elements S{_n} (n is the length of the array)
  • Maintain an array a during loop traversal, where a[i] represents the sum of elements with subscripts from 0 to i;
  • When finding the specific interval sum, the above conclusion can be used.

Time complexity analysis of the algorithm:        

The time complexity of the prefix sum algorithm can reach O(n).

example

1. Link: 3956. Truncated Array - AcWing Question Bank

 

The idea is shown in the figure on the right, and it is not difficult to get the steps to solve the problem:

  1. Traverse the array first, preprocess to find the sum s of the array, if s is not a multiple of three, it means there is no solution;
  2. Enumerate the second point from front to back, and judge that the prefix sum of the array at this time is (3 / s) * 2:
    1. Yes: then enumerate the first point, and find the number of points whose prefix sum of the previous array is 3/s, which is cnt;
    2. No: then continue to enter the next cycle
  3. Sum the cnt obtained each time to get the output of all the schemes ans. Finish.

The Java code for this question is as follows:

import java.util.Scanner;

import static java.lang.System.exit;

public class Acwing_3959 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n + 5];
        int[] s = new int[n + 5];  // 表示数组的前n项和
        long ans = 0, sum = 0, cnt = 0;
   // ans表示总的方案数,sum表示数组的综合,cnt表示在当前元素之前有多少个第一个元素符合要求
        for (int i = 1; i <= n; i++) {
            nums[i] = scanner.nextInt();
            sum += nums[i];  // 计算数组的总和
            if(i == 1) s[i] = nums[i];
            else s[i] = nums[i] + s[i - 1];   // 计算数组的前n项和
        }
        if(sum % 3 != 0 || n < 3) {
            System.out.println(0);
            exit(0);
        }
        long average = sum / 3;
        for (int i = 1; i < n; i++) {
            if(s[i] == average * 2) ans += cnt; 
            if(s[i] == average) ++cnt;
        }
        System.out.println(ans);
    }
}

Here are some tips to keep in mind when completing this question:

  • It is better to start the prefix and array from subscript 1, which can avoid the situation where the array elements are all 0 and it is difficult to calculate the number of sub-arrays;

difference


concept

I learned about the prefix sum in the front, and there are differences in a class of algorithms that are very similar to the prefix sum. The same is done on the string, the prefix sum can be calculated in o(1) time, and the sum of the elements in a certain range of the array can be calculated, and the difference can be added to the elements in a certain range of the array in the average o(n) time (or subtract) a number.

  The algorithm idea is as follows:

Suppose we need to add a number c to the elements with subscripts 2 to 3 in the array, then we can maintain a differential array b. At the beginning, all the elements of b are 0, change b[2] to c, and at the same time change b[4] Change to -c, and then calculate the prefix sum s[i] of the difference array, s[i] means the prefix sum at the subscript i. Finally, add the elements of the original array to the prefix sum of the corresponding difference array. It is not difficult to prove that the time complexity of this method is o(n), and it has nothing to do with the number of operations. That is to say, using the difference algorithm, no matter how many times the interval of the array is increased, the time complexity of the algorithm is always O(n).

Note that prefix summing in a difference array is a trivial operation. Because it is necessary to traverse the original array and the difference array to add array elements, you only need to use the  S{_n} = S{_{n - 1}} + a{_n}prefix sum before adding the original array. Using a prefix sum array can complete the calculation without affecting the overall time complexity of the algorithm. prefix and .

 

The above statement is a kind of thinking that is often used in actual problem solving, and now the definition of difference is given:

Definition : Each element of the differential array can be the difference between the current element of the original array and its previous element (i≠0), and the first element of the differential array is equal to the first element of the original array;

Inference : The prefix sum of the difference array is the original array.

Proof: Suppose the original array is:

                        int arr = {2, 3, 4, 6, 7};

  It is not difficult to find the difference array as:

                        int b = {2, 1, 1, 2, 1}; Calculate the prefix sum of this difference array to get the original array.

It is not difficult to prove that for the general case, this inference still holds.

Extra reminder: In actual operation, we need to count the subscripts of difference arrays and element groups from 1. Due to the limitation of the author's level, the specific principle of doing so cannot be given for the time being, but a lot of practice has proved that this is indeed true. In fact, many problems can be avoided virtually.

example

Topic Link: 3729. Change Array Elements - AcWing Question Bank

 

Figure 1 Acwing_3729 (Screenshot of Example 1)

Problem-solving ideas:

According to the idea of ​​difference, the array to be output can be regarded as the original array, and a difference array is maintained in the program. According to experience, the subscripts of both the difference array and the original array should start from 1. The concept of "logical addition" is used to complete the addition of the prefix sum of the differential array to the original array, that is, 1 + 1 = 1. The requirement to change the last three elements of the original array to 1 can be converted into logical addition 1. The length of the original array is changing, but it is not difficult to find the front and rear subscripts of the elements that need to be logically added by 1 every time. Then the overall requirement of this question is to logically add 1 to the specified interval of the original array, and there are many operations. If you use the general method, it is not difficult to see that the time limit will definitely be exceeded, so the method of difference is one of the positive solutions to this question.

The problem-solving steps are as follows:

  1. Prepare a difference array with all 0s, the length is large enough;
  2. Simultaneously traverse the original array and the integer array of the problem setting. Since the integer array of the problem setting only needs to be used once, the dumping of the array can be canceled, and the input and use of the array can be combined, and a variable ret can be used instead of the array;
  3. Convert the obtained re into the subscript interval of the differential array (it is not difficult to prove that the subscript interval is [i - ret + 1, i +1]), and then give the two corresponding elements of the differential array (k[i - ret + 1] and k[i + 1]) plus 1 and -1.
  4. Maintain the prefix and array of the difference array, and add it to the original array. Note: "Logical addition" cannot be used when adding the prefix sum of the differential array to the original array, because the prefix sum array represents the multiplicity of 1, 1 means that one 1 is added, and 2 means that two 2s are added. Only after all the prefix and array processing are completed can the number greater than 1 be changed to 1, and the number less than 1 to be changed to 0;
  5. Output the original array after logical processing. Finish.

The Java for this question is as follows:

import java.util.Scanner;

public class Acwing_3729 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();
        int[] k = new int[100005];   // 差分数组
        while(t-- > 0){
            int n = scanner.nextInt();
            int[] arr = new int[n + 5];
            for(int i = 1; i <= n; i++){
                int ret = scanner.nextInt();
                if(i - ret + 1 <= 1) k[1] += 1;
                else k[i - ret + 1] += 1;
                k[i + 1] += -1;
            }
            for (int i = 1; i <= n; i++) {
                arr[i] = arr[i - 1] + k[i];
                k[i] = 0;
                System.out.printf("%d ", arr[i] > 0 ? 1 : 0);
            }
            k[n + 1] = 0;
            System.out.println();
        }
    }
}

 PS: The rich text editor at station c is really difficult to handle. This is my previous blog, which has been written in word, and it took me a long time to switch to this one. Especially the formula editor is really uncomfortable.

Can @SoftwareTeacher optimize the following~~~~~

Guess you like

Origin blog.csdn.net/qq_61567032/article/details/129152315