📜  前缀和数组–竞争性编程中的实现和应用

📅  最后修改于: 2021-06-26 13:35:51             🧑  作者: Mango

给定大小为n的数组arr [],其前缀和数组是大小相同的另一个数组prefixSum [],因此prefixSum [i]的值为arr [0] + arr [1] + arr [2]…arr [一世]。

例子 :

Input  : arr[] = {10, 20, 10, 5, 15}
Output : prefixSum[] = {10, 30, 40, 45, 60}

Explanation : While traversing the array, update 
the element by adding it with its previous element.
prefixSum[0] = 10, 
prefixSum[1] = prefixSum[0] + arr[1] = 30, 
prefixSum[2] = prefixSum[1] + arr[2] = 40 and so on.

为了填充前缀求和数组,我们要遍历索引1到最后,并继续在前缀求和数组中添加具有先前值的当前元素。
下面是实现:

C++
// C++ program for Implementing
// prefix sum array
#include 
using namespace std;
 
// Fills prefix sum array
void fillPrefixSum(int arr[], int n, int prefixSum[])
{
    prefixSum[0] = arr[0];
 
    // Adding present element
    // with previous element
    for (int i = 1; i < n; i++)
        prefixSum[i] = prefixSum[i - 1] + arr[i];
}
 
// Driver Code
int main()
{
    int arr[] = { 10, 4, 16, 20 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int prefixSum[n];
 
    fillPrefixSum(arr, n, prefixSum);
    for (int i = 0; i < n; i++)
        cout << prefixSum[i] << " ";
}


Java
// Java Program for Implementing
// prefix sum arrayclass
class Prefix {
    // Fills prefix sum array
    static void fillPrefixSum(int arr[], int n,
                              int prefixSum[])
    {
        prefixSum[0] = arr[0];
 
        // Adding present element
        // with previous element
        for (int i = 1; i < n; ++i)
            prefixSum[i] = prefixSum[i - 1] + arr[i];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 10, 4, 16, 20 };
        int n = arr.length;
        int prefixSum[] = new int[n];
 
        fillPrefixSum(arr, n, prefixSum);
 
        for (int i = 0; i < n; i++)
            System.out.print(prefixSum[i] + " ");
        System.out.println("");
    }
}
 
// This Code is Contributed by Saket Kumar


Python3
# Python Program for Implementing
# prefix sum array
 
# Fills prefix sum array
def fillPrefixSum(arr, n, prefixSum):
 
    prefixSum[0] = arr[0]
 
    # Adding present element
    # with previous element
    for i in range(1, n):
        prefixSum[i] = prefixSum[i - 1] + arr[i]
 
# Driver code
arr =[10, 4, 16, 20 ]
n = len(arr)
 
prefixSum = [0 for i in range(n + 1)]
 
fillPrefixSum(arr, n, prefixSum)
 
for i in range(n):
    print(prefixSum[i], " ", end ="")
 
# This code is contributed
# by Anant Agarwal.


C#
// C# Program for Implementing
// prefix sum arrayclass
using System;
 
class GFG {
    // Fills prefix sum array
    static void fillPrefixSum(int[] arr, int n,
                              int[] prefixSum)
    {
        prefixSum[0] = arr[0];
 
        // Adding present element
        // with previous element
        for (int i = 1; i < n; ++i)
            prefixSum[i] = prefixSum[i - 1] + arr[i];
    }
 
    // Driver code
    public static void Main()
    {
        int[] arr = { 10, 4, 16, 20 };
        int n = arr.Length;
        int[] prefixSum = new int[n];
 
        fillPrefixSum(arr, n, prefixSum);
 
        for (int i = 0; i < n; i++)
            Console.Write(prefixSum[i] + " ");
        Console.Write("");
    }
}
 
// This Code is Contributed by nitin mittal


PHP


C++14
#include 
using namespace std;
 
int find(int m, vector> q)
{
    int mx = 0;
    vector pre(5,0);
     
    for (int i = 0; i < m; i++)
    {   
        // take input a and b
        int a = q[i].first, b = q[i].second;
       
        // add 100 at first index and
        // subtract 100 from last index
       
        // pre[1] becomes 100
        pre[a-1] += 100;
          
        // pre[4] becomes -100 and this
        pre[b] -=100;   
        // continues m times as we input diff. values of a and b
    }
    for (int i = 1; i < 5; i++)
    {
        // add all values in a cumulative way
        pre[i] += pre[i - 1];
         
        // keep track of max value
        mx = max(mx, pre[i]);
    }
      
                                
    return mx;
}
 
// Driver Code
int main()
{
     
    int m = 3;
    vector> q = {{2,4},{1,3},{1,2}};
   
   
    // Function call
    cout<< find(m,q);
    return 0;
}


Python3
# Python implementation of the approach
def find( m, q):
    mx = 0
    pre = [0 for i in range(5) ]
     
    for i in range(m):
        # take input a and b
        a,b = q[i][0], q[i][1]
       
        # add 100 at first index and
        # subtract 100 from last index
       
        # pre[1] becomes 100
        pre[a-1] += 100
          
        # pre[4] becomes -100 and this
        pre[b] -=100; 
         
        # continues m times as we input diff. values of a and b
    for i in range(1,5):
       
        # add all values in a cumulative way
        pre[i] += pre[i - 1]
         
        # keep track of max value
        mx = max(mx, pre[i])                            
    return mx
   
# Driver Code
m = 3
q = [[2,4],[1,3],[1,2]]
 
# Function call
print(find(m,q))
 
# This code is contributed by rohitsingh07052


输出:

10 14 30 50

应用范围:

  • 数组的平衡索引:数组的平衡索引是这样的索引,即较低索引处的元素之和等于较高索引处的元素之和。
  • 查找是否存在一个总和为0的子数组:给定一个正负数数组,查找是否存在一个总和为0的子数组(大小至少为1)。
  • 最大子数组大小,以使该大小的所有子数组的总和小于k:给定一个n个正整数和一个正整数k的数组,任务是找到最大子数组大小,以使该大小的所有子数组都具有元素之和小于k。
  • 找到可以写为大多数连续质数之和的质数:给定一系列限制。对于每个限制,找到可以写为小于或等于限制的最连续的素数之和的素数。
  • 两个二进制数组中具有相同总和的最长跨度:给定两个二进制数组arr1 []和arr2 [],其大小为n。求出最长公共跨度(i,j)的长度,其中j> = i,使得arr1 [i] + arr1 [i + 1] +…。 + arr1 [j] = arr2 [i] + arr2 [i + 1] +…。 + arr2 [j]。
  • 最大子数组求和模m:给定一个n个元素和一个整数m的数组。任务是找到其子阵列模m的总和的最大值,即找到每个子阵列mod m的总和并打印此模运算的最大值。
  • 最大子数组大小,以使该大小的所有子数组的总和小于k:给定一个n个正整数和一个正整数k的数组,任务是找到最大子数组大小,以使该大小的所有子数组都具有元素之和小于k。
  • 在n个范围内出现的最大整数:给定n个形式为L和R的范围,任务是在所有范围内找到最大出现的整数。如果存在多个这样的整数,则打印最小的整数。
  • 购买所有硬币的最低成本,每个硬币允许有k个额外的硬币:您会得到N个不同面额的硬币的列表。您可以支付相当于任何1个硬币的金额,并可以获取该硬币。此外,一旦您支付了硬币,我们最多可以再选择K个硬币,并且可以免费获得。任务是找到在给定的K值下获取所有N个硬币所需的最小数量。
  • 以任意概率分布方式的随机数生成器:给定n个数字,每个数字都有一定的出现频率。返回一个随机数,其概率与其发生频率成正比。

一个示例问题:
考虑一个大小为n且初始值均为0的数组。执行从索引’a’到’b’的给定’m’加法运算,并评估数组中的最高元素。加法运算会将a到b的所有元素(包括两个元素)相加100。
例子 :

Input : n = 5 // We consider array {0, 0, 0, 0, 0}
        m = 3.
        a = 2, b = 4.
        a = 1, b = 3.
        a = 1, b = 2.
Output : 300

Explanation : 

After I operation -
A : 0 100 100 100 0

After II operation -
A : 100 200 200 100 0

After III operation -
A : 200 300 200 100 0

Highest element : 300

一种简单的方法是将循环运行“ m”次。输入a和b并运行从a到b的循环,将所有元素加100。
使用Prefix Sum Array的有效方法:

1 : Run a loop for 'm' times, inputting 'a' and 'b'.
2 : Add 100 at index 'a-1' and subtract 100 from index 'b'.
3 : After completion of 'm' operations, compute the prefix sum array.
4 : Scan the largest element and we're done.

我们所做的是在’a’处添加100,因为这将在采用前缀求和数组的同时向所有元素添加100。从’b + 1’减去100将逆向从’b’开始加100的元素所做的更改。
为了更好的理解:

After I operation -
A : 0 100 0 0 -100 
Prefix Sum Array : 0 100 100 100 0

After II operation -
A : 100 100 0 -100 -100
Prefix Sum Array : 100 200 200 100 0

After III operation -
A : 200 100 -100 -100 -100
Prefix Sum Array : 200 300 200 100 0

Final Prefix Sum Array : 200 300 200 100 0 

The required highest element : 300

C++ 14

#include 
using namespace std;
 
int find(int m, vector> q)
{
    int mx = 0;
    vector pre(5,0);
     
    for (int i = 0; i < m; i++)
    {   
        // take input a and b
        int a = q[i].first, b = q[i].second;
       
        // add 100 at first index and
        // subtract 100 from last index
       
        // pre[1] becomes 100
        pre[a-1] += 100;
          
        // pre[4] becomes -100 and this
        pre[b] -=100;   
        // continues m times as we input diff. values of a and b
    }
    for (int i = 1; i < 5; i++)
    {
        // add all values in a cumulative way
        pre[i] += pre[i - 1];
         
        // keep track of max value
        mx = max(mx, pre[i]);
    }
      
                                
    return mx;
}
 
// Driver Code
int main()
{
     
    int m = 3;
    vector> q = {{2,4},{1,3},{1,2}};
   
   
    // Function call
    cout<< find(m,q);
    return 0;
}

Python3

# Python implementation of the approach
def find( m, q):
    mx = 0
    pre = [0 for i in range(5) ]
     
    for i in range(m):
        # take input a and b
        a,b = q[i][0], q[i][1]
       
        # add 100 at first index and
        # subtract 100 from last index
       
        # pre[1] becomes 100
        pre[a-1] += 100
          
        # pre[4] becomes -100 and this
        pre[b] -=100; 
         
        # continues m times as we input diff. values of a and b
    for i in range(1,5):
       
        # add all values in a cumulative way
        pre[i] += pre[i - 1]
         
        # keep track of max value
        mx = max(mx, pre[i])                            
    return mx
   
# Driver Code
m = 3
q = [[2,4],[1,3],[1,2]]
 
# Function call
print(find(m,q))
 
# This code is contributed by rohitsingh07052
输出
300

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。