Find the maximum range [L,R] whose sum is divisible by M

Given an array arr[] consisting of positive numbers, the task is to find the maximum range [L, R] whose sum is divisible by M. If there is no range present return -1.

Examples:

Input: arr[] = {3, 7, 5, 2, 5, 10}, M = 3
Output: 1 3
Explanation: Sum of numbers from 1 to 3 is 3+7+5 which is 15.



Input :
A[] = {4, 8, 12, 16, 20}
M = 11
Output :
-1

Naive Approach: A naive approach is that we can iterate through all possible L and R in the array and check if the sum is divisible. If it is, then store the length of the array.

Efficient Approach: The idea here is to use a prefix sum array.

  • Initially, the prefix sum of the values is calculated.
  • Once the prefix sum is calculated, every value is replaced by the value modulo M.
  • The indices where the final value is equal is the range where the sum is perfectly divisible by M.
  • The maximum range of the same values is found.

Below is the implementation of the above approach,

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the above approach.
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the maximum range
// whose sum is divisible by M.
pair<int, int> maxrange(int n,
                        int a[], int m)
{
    int pre[n + 5];
    map<int, set<int> > mpp;
    int value, l, r, lans = -1,
                     rans = -1, ans = 0;
  
    // Calculate the prefix sum
    pre[0] = a[0];
    for (int i = 1; i < n; i++) {
        pre[i] = a[i] + pre[i - 1];
    }
  
    // Replacing the values with modulo M
    // and inserting the indices into the map
    for (int i = 0; i < n; i++) {
        pre[i] = pre[i] % m;
        mpp[pre[i]].insert(i);
    }
  
    // Calculate the range [L, R]
    for (auto it = mpp.begin(); it != mpp.end(); it++) {
        if (it->first == 0) {
            value = *((it->second).rbegin()) + 1;
            l = 1;
            r = value;
        }
        else {
            value = *((it->second).rbegin())
                    - *((it->second.begin()));
            l = *((it->second.begin())) + 2;
            r = *((it->second).rbegin()) + 1;
        }
        if (value > ans && l <= r) {
            ans = value;
            lans = l;
            rans = r;
        }
    }
  
    return make_pair(lans, rans);
}
  
// Driver code
int main()
{
    int A[] = { 3, 7, 5, 2, 5, 10 };
    int N = sizeof(A) / sizeof(A[0]);
    int M = 3;
    pair<int, int> value = maxrange(N, A, M);
    if (value.first == -1) {
        cout << -1 << "\n";
    }
    else {
        cout << value.first << " "
             << value.second << "\n";
    }
    return 0;
}

chevron_right


Output:

1 3



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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 Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.