Maximum value in an array after m range increment operations

Consider an array of size n with all initial values as 0, we need to perform following m range increment operations.

increment(a, b, k) : Increment values from 'a'
                     to 'b' by 'k'.    

After m operations, we need to calculate the maximum of the values in the array.

Examples:

Input : n = 5 m = 3
        a = 0, b = 1, k = 100
        a = 1, b = 4, k = 100
        a = 2, b = 3, k = 100
Output : 882
Explanation:
Initially array = {0, 0, 0, 0, 0}
After first operation:
array = {100, 100, 0, 0, 0}
After second operation:
array = {100, 200, 100, 100, 100}
After third operation:
array = {100, 200, 200, 200, 100}
Maximum element after m operations 
is 200.

Input : n = 4 m = 3
        a = 1, b = 2, k = 603
        a = 0, b = 0, k = 286
        a = 3, b = 3, k = 882
Output : 882
Explanation:
Initially array = {0, 0, 0, 0}
After first operation:
array = {0, 603, 603, 0}
After second operation:
array = {286, 603, 603, 0}
After third operation:
array = {286, 603, 603, 882}
Maximum element after m operations 
is 882.

A naive method is to perform each operation on given range and then at last find the maximum number.

// C++ implementation of simple approach to
// find maximum value after m range increments.
#include<bits/stdc++.h>
using namespace std;

// Function to find the maximum element after
// m operations
int findMax(int n, int a[], int b[], int k[], int m)
{
    int arr[n];
    memset(arr, 0, sizeof(arr));

    // start performing m operations
    for (int i = 0; i< m; i++)
    {
        // Store lower and upper index i.e. range
        int lowerbound = a[i];
        int upperbound = b[i];

        // Add 'k[i]' value at this operation to
        // whole range
        for (int j=lowerbound; j<=upperbound; j++)
            arr[j] += k[i];
    }

    // Find maximum value after all operations and
    // return
    int res = INT_MIN;
    for (int i=0; i<n; i++)
        res = max(res, arr[i]);

    return res;
}

// Driver code
int main()
{
    // Number of values
    int n = 5;
    int a[] = {0, 1, 2};
    int b[] = {1, 4, 3};

    // value of k to be added at each operation
    int k[] = {100, 100, 100};

    int m = sizeof(a)/sizeof(a[0]);

    cout << "Maximum value after 'm' operations is "
        << findMax(n, a, b, k, m);
    return 0;
}

Output:

Maximum value after 'm' operations is 200

Time Complexity: O(m * max(range)). Here max(range) means maximum elements to which k is added in a single operation.

Efficient method : The idea is similar to this post.

Perform two things in a single operation:
1- Add k-value to only lower_bound of a range.
2- Reduce upper_bound + 1 index by k-value.

After all operations, add all values, check the maximum sum and print maximum sum.

// C++ implementation of simple approach to
// find maximum value after m range increments.
#include<bits/stdc++.h>
using namespace std;

// Function to find maximum value after 'm' operations
int findMax(int n, int m, int a[], int b[], int k[])
{
    int arr[n+1];
    memset(arr, 0, sizeof(arr));

    // Start performing 'm' operations
    for (int i=0; i<m; i++)
    {
        // Store lower and upper index i.e. range
        int lowerbound = a[i];
        int upperbound = b[i];

        // Add k to the lower_bound
        arr[lowerbound] += k[i];

        // Reduce upper_bound+1 indexed value by k
        arr[upperbound+1] -= k[i];
    }

    // Find maximum sum possible from all values
    long long sum = 0, res = INT_MIN;
    for (int i=0; i < n; ++i)
    {
        sum += arr[i];
        res = max(res, sum);
    }

    // return maximum value
    return res;
}

// Driver code
int main()
{
    // Number of values
    int n = 5;

    int a[] = {0, 1, 2};
    int b[] = {1, 4, 3};
    int k[] = {100, 100, 100};

    // m is number of operations.
    int m = sizeof(a)/sizeof(a[0]);

    cout << "Maximum value after 'm' operations is "
         << findMax(n, m, a, b, k);
    return 0;
}

Output:

Maximum value after 'm' operations is 200

Time complexity : O(m + n)

This article is contributed by Sahil Chhabra (akku). If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice





Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the link here.