Open In App

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

Last Updated : 12 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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, 

CPP
// 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; 
} 
Java
import java.util.*;

class GFG {
    // Function to find the maximum range
    // whose sum is divisible by M.
    static Pair<Integer, Integer> maxRange(int n, int[] a, int m) {
        int[] pre = new int[n + 5];
        TreeMap<Integer, TreeSet<Integer>> mpp = new TreeMap<>();
        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;
            if (!mpp.containsKey(pre[i])) {
                mpp.put(pre[i], new TreeSet<>());
            }
            mpp.get(pre[i]).add(i);
        }

        // Calculate the range [L, R]
        for (Map.Entry<Integer, TreeSet<Integer>> entry : mpp.entrySet()) {
            int key = entry.getKey();
            TreeSet<Integer> indices = entry.getValue();
            if (key == 0) {
                value = indices.last() + 1;
                l = 1;
                r = value;
            } else {
                value = indices.last() - indices.first();
                l = indices.first() + 2;
                r = indices.last() + 1;
            }
            if (value > ans && l <= r) {
                ans = value;
                lans = l;
                rans = r;
            }
        }

        return new Pair<>(lans, rans);
    }

    // Driver code
    public static void main(String[] args) {
        int[] A = { 3, 7, 5, 2, 5, 10 };
        int N = A.length;
        int M = 3;
        Pair<Integer, Integer> value = maxRange(N, A, M);
        if (value.getKey() == -1) {
            System.out.println(-1);
        } else {
            System.out.println(value.getKey() + " " + value.getValue());
        }
    }

    // Pair class to represent a pair of values
    static class Pair<T, U> {
        T first;
        U second;

        public Pair(T first, U second) {
            this.first = first;
            this.second = second;
        }

        public T getKey() {
            return first;
        }

        public U getValue() {
            return second;
        }
    }
}
Python3
# Function to find the maximum range
# whose sum is divisible by M.
def maxrange(n, a, m):
    pre = [0] * (n + 5)
    mpp = {}
    value, l, r, lans, rans, ans = -1, -1, -1, 0, 0, 0

    # Calculate the prefix sum
    pre[0] = a[0]
    for i in range(1, n):
        pre[i] = a[i] + pre[i - 1]

    # Replacing the values with modulo M
    # and inserting the indices into the map
    for i in range(n):
        pre[i] = pre[i] % m
        if pre[i] not in mpp:
            mpp[pre[i]] = set()
        mpp[pre[i]].add(i)

    # Calculate the range [L, R]
    for key in mpp:
        if key == 0:
            value = max(mpp[key]) + 1
            l, r = 1, value
        else:
            value = max(mpp[key]) - min(mpp[key])
            l, r = min(mpp[key]) + 2, max(mpp[key]) + 1
        if value > ans and l <= r:
            ans = value
            lans = l
            rans = r

    return (lans, rans)

# Driver code
A = [3, 7, 5, 2, 5, 10]
N = len(A)
M = 3
value = maxrange(N, A, M)
if value[0] == -1:
    print(-1)
else:
    print(value[0], value[1])

    
    
    
# This code is contributed by shiv1o43g
C#
using System;
using System.Collections.Generic;

class GFG
{
    // Function to find the maximum range
    // whose sum is divisible by M.
    static (int, int) MaxRange(int n, int[] a, int m)
    {
        int[] pre = new int[n + 5];
        SortedDictionary<int, SortedSet<int>> mpp = new SortedDictionary<int, SortedSet<int>>();
        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;
            if (!mpp.ContainsKey(pre[i]))
            {
                mpp[pre[i]] = new SortedSet<int>();
            }
            mpp[pre[i]].Add(i);
        }

        // Calculate the range [L, R]
        foreach (var entry in mpp)
        {
            int key = entry.Key;
            SortedSet<int> indices = entry.Value;
            if (key == 0)
            {
                value = indices.Max + 1;
                l = 1;
                r = value;
            }
            else
            {
                value = indices.Max - indices.Min;
                l = indices.Min + 2;
                r = indices.Max + 1;
            }
            if (value > ans && l <= r)
            {
                ans = value;
                lans = l;
                rans = r;
            }
        }

        return (lans, rans);
    }

    // Driver code
    public static void Main(string[] args)
    {
        int[] A = { 3, 7, 5, 2, 5, 10 };
        int N = A.Length;
        int M = 3;
        var value = MaxRange(N, A, M);
        if (value.Item1 == -1)
        {
            Console.WriteLine(-1);
        }
        else
        {
            Console.WriteLine($"{value.Item1} {value.Item2}");
        }
    }
}
JavaScript
// Function to find the maximum range 
// whose sum is divisible by M.
function maxRange(n, a, m) {
    let pre = new Array(n + 5).fill(0);
    let mpp = {};
    let value = -1;
    let l = -1;
    let r = -1;
    let lans = 0;
    let rans = 0;
    let ans = 0;

    // Calculate the prefix sum
    pre[0] = a[0];
    for (let 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 (let i = 0; i < n; i++) {
        pre[i] = pre[i] % m;
        if (!mpp[pre[i]]) {
            mpp[pre[i]] = new Set();
        }
        mpp[pre[i]].add(i);
    }

    // Calculate the range [L, R]
    for (let key in mpp) {
        key = parseInt(key);
        if (key === 0) {
            value = Math.max(...mpp[key]) + 1;
            l = 1;
            r = value;
        } else {
            value = Math.max(...mpp[key]) - Math.min(...mpp[key]);
            l = Math.min(...mpp[key]) + 2;
            r = Math.max(...mpp[key]) + 1;
        }
        if (value > ans && l <= r) {
            ans = value;
            lans = l;
            rans = r;
        }
    }

    return [lans, rans];
}

// Driver code
const A = [3, 7, 5, 2, 5, 10];
const N = A.length;
const M = 3;
const value = maxRange(N, A, M);

if (value[0] === -1) {
    console.log(-1);
} else {
    console.log(value[0], value[1]);
}

Output
1 3

Article Tags :
Practice Tags :

Similar Reads