One-dimensional prefix sum

One-dimensional prefix sum

The function of the prefix and the array is to change the query of the interval to the query of the end of the interval.
It is often used to calculate the sum of the Lth element to the Rth element of a sequence, that is, the interval summation problem of the sequence

Prefix and-
example of prefixSum :

Suppose the original array nums [] = {0,5,6,7,8};
can thus be an array of recursive obtained prefix and the array prefixSums [] = {5,11,18,26};
Note: the prefix and array subscripts Store values ​​starting from 1

The recursion process is as follows:
prefixSums[ 0] = nums[ 0] = 0;

prefixSums[ 1 ] = nums[ 0 ] + nums[ 1 ] = prefixSums[ 0 ] + nums[ 1 ] = 5 ;

prefixSums[ 2 ] = nums[ 0 ] + nums[ 1 ] + nums[ 2 ]= prefixSums[ 1 ] + nums[ 2 ] = 11 ;

prefixSums[ 3 ] = nums[ 0 ] + nums[ 1 ] + nums[ 2 ] + nums[ 3 ]= prefixSums[ 2 ] + nums[ 3 ] = 18 ;

prefixSums[ 4 ] = nums[ 0 ] + nums[ 1 ] + nums[ 2 ] + nums[ 3 ] + nums[ 4 ] = prefixSums[ 3 ] + nums[ 4 ] = 26 ;

Summarized from the above:
prefixSums[ i] = prefixSum[ i-1] + nums[ i ];

Focus! ! ! :
Use prefixSum[ R]-prefixSum[ L-1] to calculate the sum from the Lth element to the Rth sum element

Code implementation of prefix and array:

#include <iostream>

using namespace std;

const int N = 10010;
int nums[N];//原数组
int prefixSums[N];//前缀和数组

int main()
{
    
    
    int n;
    scanf("%d",&n);
    
    //prefixSums[i - 1]的下标从0开始,所以i要从1开始
    for (int i = 1;i <= n;i++)
    {
    
    
        scanf("%d",&nums[i]);
        
        //核心代码
        prefixSums[i] = prefixSums[i - 1] + nums[i];
    }
    for (int i = 1;i <= n;i++) printf("%d ",prefixSums[i]);
    return 0;
}

Example:
Link to the original question.
There are N positive integers placed in array A. Now you are required to find and output such an array:
the i-th number of this array is the first number of array A to the i-th number of array A The sum.
Enter
1 positive integer in the first line: N, the range of N is [1, 100].
N positive integers in the second line: the range is [1, 10000].
Output
N positive integers.
Sample input
6
2 6 1 9 7 3
Sample output
2 8 9 18 25 28

AC code:

#include <cstdio>
#include <iostream>

using namespace std;

const int N = 110;
int prefixSum[N];//定义前缀和数组
int a[N];//定义原数组

int main()
{
    
    
    int n;
    scanf("%d",&n);
    
    //统一从1开始计数
    for (int i = 1;i <= n;i++)
    {
    
    
        scanf("%d",&a[i]);
        prefixSum[i] = prefixSum[i - 1] + a[i];
    }
    for (int j = 1;j <= n;j++) printf("%d ",prefixSum[j]);
    return 0;
}

Example Question 2
Link to the original question
Title description
Given an array of length n, find the sum of the elements in a certain interval [L, R] of the array arr.
Enter
a number n in the first line, indicating the length of the array.
The second line contains n integers, and each integer is separated by a space to indicate the data of the array.
A number m in the third line indicates the number of operations to be performed.
Starting from the fourth line to m+3 line, each line includes two arrays L and R, which represent the array range of the operation.
The output has a
total of m lines, each line has an integer, which represents the sum of the corresponding interval elements.
Sample input Copy
10
5 2 -3 1 -5 10 150 300 1200 93
4
1 3
2 5
1 8
1 10
Sample output Copy
4
-5
460
1753
prompt
[data range]
1 ⩽ m ⩽ n ⩽10 ^ 5
− 10 ^ 12 ⩽ ai ⩽10 ^ 12
1 ⩽ R ⩽ L⩽10 ^ 5

#include <iostream>
#include <cstdio>
 
using namespace std;
 
const int N = 100010;
long long a[N];//int 最大值是2147483647,而−10^12⩽ai⩽10^12
 
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for (int i = 1;i <= n;i++) scanf("%lld",&a[i]);
     
    int m;
    scanf("%d",&m);
    while (m--)
    {
    
    
        long long int ans = 0;
        int l,r;
        scanf("%d%d",&l,&r);
        for (int j = l;j <= r;j++) ans += a[j];
        printf("%lld\n",ans);
    }
    return 0;
}

Note: The above naive algorithm can logically be AC, but I don't know why. . .

Insert picture description here
The big guy who asked ACM didn't see it, and finally I changed the code to this. Whoever found a code that can be A is welcome to correct me.

After a while, continue to blog more.
Good guy, it turns out that the code is staggered with the question number. It's so stupid to open the door to the stupid. The following is the prefix, code and idea of ​​the previous example

由题意得
ans = a[ l ] + a[ l + 1] + … … + a[ r - 1] + a[ r ]
= ( a[ 0 ] + a[ 1 ] + a[ 2 ] + … … + a[ l - 1] ) + a[ l ] + a[ l + 1] + … … + a[ r - 1] + a[ r ] - ( a[ 0 ] + a[ 1 ] + a[ 2 ] + … … + a[ l - 1] )
观察得
( a[ 0 ] + a[ 1 ] + a[ 2 ] + … … + a[ l - 1] ) + a[ l ] + a[ l + 1] + … … + a[ r - 1] + a[ r ] = prefixSum[ r ];
( a[ 0 ] + a[ 1 ] + a[ 2 ] + … … + a[ l - 1] ) = prefixSum[l - 1];

Namely prefix and core code:
ans = prefixSum[ r]-prefixSum[l-1]

#include <cstdio>
#include <iostream>

using namespace std;

const int N = 100010;
long long prefixSum[N];//前缀和数组
long long a[N];//原数组


int main()
{
    
    
    int n;
    scanf("%d",&n);
    
    //从1开始,数组下标就刚好是第几位数
    for (int i = 1;i <= n;i++)
    {
    
    
        scanf("%lld",&a[i]);
        
        //前缀和数组
        prefixSum[i] = prefixSum[i - 1] + a[i];
    }
    
    int m;
    scanf("%d",&m);
    for (int i = 1;i <= m;i++)
    {
    
    
        int l,r;
        long long ans = 0;
        scanf("%d%d",&l,&r);
        ans = prefixSum[r] - prefixSum[l - 1];
        printf("%lld\n",ans);
    }
    
    return 0;
}

Of course, compared to the previous naive algorithm, the prefix sum optimizes the time complexity from O(n ^ 2) level to O( n) level

Guess you like

Origin blog.csdn.net/smallrain6/article/details/112757186