Subsequences of size three in an array whose sum is divisible by m

Given an array A[] (1<=A_i<=10^9) of size N (1<=N<=10^5), find number of subsequences of length 3 whose sum is divisible by M (1<=M<=10^3).
Examples:

Input  : A[] = {1, 2, 4, 3}
           M = 3 
Output : 2
Explanation : We can choose two such 
subsequence of length 3 such that its 
sum is divisible by 3 -> {1, 2, 3} ans 
{2, 4, 3}



Brute Force Approach: We use 3 nested loops to traverse all the sub sequences of length 3 to count all such sub sequence which satisfy the given condition.

Here the brute force solution will work in O(N^3)

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// Brute Force Implementation (Time Complexity :
// O(N^3)) C++ program to find count of subsequences of size
// three divisible by M.
#include <bits/stdc++.h>
  
using namespace std;
  
int coutSubSeq(int A[], int N, int M)
{
    int sum = 0;
    int ans = 0;
  
    // Three nested loop to find all the sub 
    // sequences of length three in the given 
    // array A[].
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            for (int k = j + 1; k < N; k++) {
                sum = A[i] + A[j] + A[k];
  
                // checking if the sum of the chosen
                // three number is divisible by m.
                if (sum % M == 0)
                    ans++;
            }
        }
    }
    return ans;
}
  
// Driver code
int main()
{
    int M = 3;
    int A[] = { 1, 2, 4, 3 };
    int N = sizeof(A)/sizeof(A[0]);
    cout << coutSubSeq(A, N, M);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find count of
// subsequences of size three
// divisible by M.
import java.io.*;
  
class GFG {
      
    static int coutSubSeq(int A[], int N,
                                   int M)
    {
        int sum = 0;
        int ans = 0;
       
        // Three nested loop to find all the
        // sub sequences of length three in
        // the given array A[].
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                for (int k = j + 1; k < N; k++) {
                    sum = A[i] + A[j] + A[k];
       
                    // checking if the sum of the
                    // chosen three number is 
                    // divisible by m.
                    if (sum % M == 0)
                        ans++;
                }
            }
        }
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int M = 3;
        int A[] = { 1, 2, 4, 3 };
        int N = A.length;
        System.out.println(coutSubSeq(A, N, M));
    }
}
  
/*This code is contributed by Nikita Tiwari*/

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to find count of
# subsequences of size three 
# divisible by M.
  
def coutSubSeq(A, N,M) :
    sum = 0
    ans = 0
   
    # Three nested loop to find all the
    # sub sequences of length three in 
    # the given array A[].
    for i in range(0, N) :
        for j in range(i + 1, N) :
            for k in range(j + 1, N) :
                sum = A[i] + A[j] + A[k]
   
                # checking if the sum of 
                # the chosen three number
                # is divisible by m.
                if (sum % M == 0) :
                    ans = ans + 1
    return ans
      
# Driver code
M = 3
A = [ 1, 2, 4, 3 ]
N = len(A)
print coutSubSeq(A, N, M)
  
# This code is contributed by Nikita Tiwari.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find count of subsequences 
// of size three divisible by M.
using System;
  
class GFG {
      
    static int coutSubSeq(int[] A, int N, int M)
    {
        int sum = 0;
        int ans = 0;
      
        // Three nested loop to find all the
        // sub sequences of length three in
        // the given array A[].
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                for (int k = j + 1; k < N; k++)
                {
                    sum = A[i] + A[j] + A[k];
      
                    // checking if the sum of
                    // the chosen three number
                    // is divisible by m.
                    if (sum % M == 0)
                        ans++;
                }
            }
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int M = 3;
        int []A = { 1, 2, 4, 3 };
        int N = A.Length;
        Console.WriteLine(coutSubSeq(A, N, M));
    }
}
  
// This code is contributed by anuj_67.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// Brute Force Implementation (Time Complexity :
// O(N^3)) PHP program to find count of subsequences of size
// three divisible by M.
  
function coutSubSeq($A, $N, $M)
{
    $sum = 0;
    $ans = 0;
  
    // Three nested loop to find all the sub 
    // sequences of length three in the given 
    // array A[].
    for ( $i = 0; $i <$N; $i++) {
        for ( $j = $i + 1; $j < $N; $j++) {
            for ( $k = $j + 1; $k < $N; $k++) {
                $sum = $A[$i] + $A[$j] + $A[$k];
  
                // checking if the sum of the 
                // chosen three number is 
                // divisible by m.
                if ($sum % $M == 0)
                    $ans++;
            }
        }
    }
      
    return $ans;
}
  
// Driver code
    $M = 3;
    $A = array( 1, 2, 4, 3 );
    $N = count($A);
    echo coutSubSeq($A, $N, $M);
  
// This code is contributed by anuj_67.
?>

chevron_right



Output:

2

Second Approach (Efficient for small M): The above implementation takes a lot of time. So we need a better approach to solve this. Here we will use index mapping (hashing technique) to solve the problem. As we need to check if the sum of the chosen three numbers are divisible by M, we store each value under modulo M. We use a frequency array to store the number of occurrence of each elements using index mapping techniques.

Three case may occur:
Firstly, if thrice of a number is divisible by M then we will add {{N}\choose{3}} to answer where N is frequency of that number.
Secondly, if twice of some number A added with sum number B is divisible by M then we will add {{Freq[A]}\choose{2}} * Freq[B] to the answer.
Thirdly, if all the number A, B, C that sum up to S which is divisible by M then we will add Freq[A] * Freq[B] * Freq[C] to the answer.

With this approach we can solve the problem in O(M^2) which is executable in the given time.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// O(M^2) time complexity C++ program to find 
// count of subsequences of size three
// divisible by M.
#include <iostream>
  
using namespace std;
  
int countSubSeq(int A[], int N, int M)
{
    int ans = 0;
  
    // Storing frequencies of all remainders
    // when divided by M.
    int h[M] = { 0 };
    for (int i = 0; i < N; i++) {
        A[i] = A[i] % M;
        h[A[i]]++;
    }
  
    for (int i = 0; i < M; i++) {
        for (int j = i; j < M; j++) {
  
            // including i and j in the sum rem
            // calculate the remainder required 
            // to make the sum divisible by M
            int rem = (M - (i + j) % M) % M;
  
            // if the required number is less than
            // j, we skip as we have already calculated 
            // for that value before. As j here starts 
            // with i and rem is less than j.
            if (rem < j)
                continue;
  
            // if satisfies the first case.
            if (i == j && rem == j)
                ans += h[i] * (h[i] - 1) * (h[i] - 2) / 6;
  
            // if satisfies the second case
            else if (i == j)
                ans += h[i] * (h[i] - 1) * h[rem] / 2;
  
            else if (i == rem)
                ans += h[i] * (h[i] - 1) * h[j] / 2;
            else if (rem == j)
                ans += h[j] * (h[j] - 1) * h[i] / 2;
  
            // if satisfies the third case
            else
                ans = ans + h[i] * h[j] * h[rem];
        }
    }
    return ans;
}
  
// Driver code
int main()
{   
    int M = 3;
    int A[] = { 1, 2, 4, 3 };
    int N = sizeof(A)/sizeof(A[0]);
    cout << countSubSeq(A, N, M);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find count of 
// subsequences of size three
// divisible by M.
import java.io.*;
import java.util.Arrays;
  
class GFG {
  
    static int countSubSeq(int A[], int N, int M)
    {
        int ans = 0;
       
        // Storing frequencies of all 
        // remainders when divided by M.
        int h[] = new int[M];
        Arrays.fill(h,0);
        for (int i = 0; i < N; i++) {
            A[i] = A[i] % M;
            h[A[i]]++;
        }
       
        for (int i = 0; i < M; i++) {
            for (int j = i; j < M; j++) {
       
                // including i and j in the sum
                // rem calculate the remainder
                // required to make the sum
                // divisible by M
                int rem = (M - (i + j) % M) % M;
       
                // if the required number is 
                // less than j, we skip as we 
                // have already calculated for
                // that value before. As j here
                // starts with i and rem is 
                // less than j.
                if (rem < j)
                    continue;
       
                // if satisfies the first case.
                if (i == j && rem == j)
                    ans += h[i] * (h[i] - 1) *
                           (h[i] - 2) / 6;
       
                // if satisfies the second case
                else if (i == j)
                    ans += h[i] * (h[i] - 1) *
                           h[rem] / 2;
       
                else if (i == rem)
                    ans += h[i] * (h[i] - 1) *
                           h[j] / 2;
                else if (rem == j)
                    ans += h[j] * (h[j] - 1) *
                           h[i] / 2;
       
                // if satisfies the third case
                else
                    ans = ans + h[i] * h[j] *
                          h[rem];
            }
        }
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int M = 3;
        int A[] = { 1, 2, 4, 3 };
        int N = A.length;
        System.out.println(countSubSeq(A, N, M));
    }
}
  
/*This code is contributed by Nikita Tiwari*/

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to find count of
# subsequences of size three
# divisible by M.
  
def countSubSeq(A, N, M) :
    ans = 0
      
    # Storing frequencies of all
    # remainders when divided by M.
    h = [0] * M
    for i in range(0,N) :
        A[i] = A[i] % M
        h[A[i]] = h[A[i]] + 1
      
    for i in range(0,M) :
        for j in range(i,M) :
              
            # including i and j in the sum
            # rem calculate the remainder
            # required to make the sum
            # divisible by M
            rem = (M - (i + j) % M) % M
              
            # if the required number is 
            # less than j, we skip as we 
            # have already calculated for
            # that value before. As j here
            # starts with i and rem is 
            # less than j.
            if (rem < j) :
                continue
                  
            # if satisfies the first case.
            if (i == j and rem == j) :
                ans = ans + h[i] * (h[i] - 1) * (h[i] - 2) / 6
                  
                  
            # if satisfies the second case
            elif (i == j) :
                ans = ans +( h[i] * (h[i] - 1) * h[rem] / 2)
       
            elif (i == rem) :
                ans = ans + h[i] * (h[i] - 1) * h[j] / 2
            elif (rem == j) :
                ans = ans + h[j] * (h[j] - 1) * h[i] / 2
       
            # if satisfies the third case
            else :
                ans = ans + h[i] * h[j] * h[rem]
              
        return ans
          
# Driver code
M = 3;
A = [ 1, 2, 4, 3 ]
N = len(A)
print(countSubSeq(A, N, M))
  
# This code is contributed by Nikita Tiwari.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find count of subsequences of
// size three divisible by M.
using System;
  
class GFG {
  
    static int countSubSeq(int []A, int N, int M)
    {
        int ans = 0;
      
        // Storing frequencies of all 
        // remainders when divided by M.
        int []h = new int[M];
      
        for (int i = 0; i < N; i++) {
            A[i] = A[i] % M;
            h[A[i]]++;
        }
      
        for (int i = 0; i < M; i++) {
            for (int j = i; j < M; j++) {
      
                // including i and j in the sum
                // rem calculate the remainder
                // required to make the sum
                // divisible by M
                int rem = (M - (i + j) % M) % M;
      
                // if the required number is 
                // less than j, we skip as we 
                // have already calculated for
                // that value before. As j here
                // starts with i and rem is 
                // less than j.
                if (rem < j)
                    continue;
      
                // if satisfies the first case.
                if (i == j && rem == j)
                    ans += h[i] * (h[i] - 1) *
                                (h[i] - 2) / 6;
      
                // if satisfies the second case
                else if (i == j)
                    ans += h[i] * (h[i] - 1) *
                                    h[rem] / 2;
      
                else if (i == rem)
                    ans += h[i] * (h[i] - 1) *
                                     h[j] / 2;
                else if (rem == j)
                    ans += h[j] * (h[j] - 1) *
                                     h[i] / 2;
      
                // if satisfies the third case
                else
                    ans = ans + h[i] * h[j] *
                                      h[rem];
            }
        }
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int M = 3;
        int []A = { 1, 2, 4, 3 };
        int N = A.Length;
        Console.WriteLine(countSubSeq(A, N, M));
    }
}
  
// This code is contributed by anuj_67.

chevron_right


PHP


Output:

2

This article is contributed by ShivamKD. 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.



My Personal Notes arrow_drop_up