Related Articles
Count sub-matrices having sum divisible ‘k’
• Difficulty Level : Hard
• Last Updated : 08 Aug, 2018

Given a n x n matrix of integers and a positive integer k. The problem is to count all sub-matrices having sum divisible by the given value k.

Examples:

Input : mat[][] = { {5, -1, 6},
{-2, 3, 8},
{7, 4, -9} }

k = 4

Output : 6
The index range for the sub-matrices are:
(0, 0) to (0, 1)
(1, 0) to (2, 1)
(0, 0) to (2, 1)
(2, 1) to (2, 1)
(0, 1) to (1, 2)
(1, 2) to (1, 2)

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach: The naive solution for this problem is to check every possible rectangle in given 2D array. This solution requires 4 nested loops and time complexity of this solution would be O(n^4).

Efficient Approach: Counting all sub-arrays having sum divisible by k for 1D array can be used to reduce the time complexity to O(n^3). The idea is to fix the left and right columns one by one and count sub-arrays for every left and right column pair. Calculate sum of elements in every row from left to right and store these sums in an array say temp[]. So temp[i] indicates sum of elements from left to right in row i. Count sub-arrays in temp[] having sum divisible by k. This count is the number of sub-matrices having sum divisible by k with left and right as boundary columns. Sum up all the counts for each temp[] with different left and right column pairs.

## C++

 // C++ implementation to count sub-matrices having sum // divisible by the value 'k' #include using namespace std;    #define SIZE 10    // function to count all sub-arrays divisible by k int subCount(int arr[], int n, int k) {     // create auxiliary hash array to count frequency     // of remainders     int mod[k];     memset(mod, 0, sizeof(mod));        // Traverse original array and compute cumulative     // sum take remainder of this current cumulative     // sum and increase count by 1 for this remainder     // in mod[] array     int cumSum = 0;     for (int i = 0; i < n; i++) {         cumSum += arr[i];            // as the sum can be negative, taking modulo         // twice         mod[((cumSum % k) + k) % k]++;     }        int result = 0; // Initialize result        // Traverse mod[]     for (int i = 0; i < k; i++)            // If there are more than one prefix subarrays         // with a particular mod value.         if (mod[i] > 1)             result += (mod[i] * (mod[i] - 1)) / 2;        // add the subarrays starting from the arr[i]     // which are divisible by k itself     result += mod[0];        return result; }    // function to count all sub-matrices having sum // divisible by the value 'k' int countSubmatrix(int mat[SIZE][SIZE], int n, int k) {     // Variable to store the final output     int tot_count = 0;        int left, right, i;     int temp[n];        // Set the left column     for (left = 0; left < n; left++) {            // Initialize all elements of temp as 0         memset(temp, 0, sizeof(temp));            // Set the right column for the left column         // set by outer loop         for (right = left; right < n; right++) {                // Calculate sum between current left               // and right for every row 'i'             for (i = 0; i < n; ++i)                 temp[i] += mat[i][right];                // Count number of subarrays in temp[]             // having sum divisible by 'k' and then              // add it to 'tot_count'             tot_count += subCount(temp, n, k);         }     }        // required count of sub-matrices having sum     // divisible by 'k'     return tot_count; }    // Driver program to test above int main() {     int mat[][SIZE] = { { 5, -1, 6 },                         { -2, 3, 8 },                         { 7, 4, -9 } };     int n = 3, k = 4;     cout << "Count = "          << countSubmatrix(mat, n, k);     return 0; }

## Java

 // Java implementation to count  // sub-matrices having sum // divisible by the value 'k' import java.util.*;    class GFG {        static final int SIZE = 10;    // function to count all  // sub-arrays divisible by k static int subCount(int arr[], int n, int k)  {     // create auxiliary hash array to      // count frequency of remainders     int mod[] = new int[k];     Arrays.fill(mod, 0);        // Traverse original array and compute cumulative     // sum take remainder of this current cumulative     // sum and increase count by 1 for this remainder     // in mod[] array     int cumSum = 0;     for (int i = 0; i < n; i++) {     cumSum += arr[i];        // as the sum can be negative,      // taking modulo twice     mod[((cumSum % k) + k) % k]++;     }        // Initialize result     int result = 0;         // Traverse mod[]     for (int i = 0; i < k; i++)        // If there are more than one prefix subarrays     // with a particular mod value.     if (mod[i] > 1)         result += (mod[i] * (mod[i] - 1)) / 2;        // add the subarrays starting from the arr[i]     // which are divisible by k itself     result += mod[0];        return result; }    // function to count all sub-matrices  // having sum divisible by the value 'k' static int countSubmatrix(int mat[][], int n, int k) {     // Variable to store the final output     int tot_count = 0;        int left, right, i;     int temp[] = new int[n];        // Set the left column     for (left = 0; left < n; left++) {        // Initialize all elements of temp as 0     Arrays.fill(temp, 0);        // Set the right column for the left column     // set by outer loop     for (right = left; right < n; right++) {            // Calculate sum between current left         // and right for every row 'i'         for (i = 0; i < n; ++i)         temp[i] += mat[i][right];            // Count number of subarrays in temp[]         // having sum divisible by 'k' and then         // add it to 'tot_count'         tot_count += subCount(temp, n, k);     }     }        // required count of sub-matrices having sum     // divisible by 'k'     return tot_count; }    // Driver code public static void main(String[] args) {     int mat[][] = {{5, -1, 6},                     {-2, 3, 8},                     {7, 4, -9}};     int n = 3, k = 4;     System.out.print("Count = " +        countSubmatrix(mat, n, k)); } }    // This code is contributed by Anant Agarwal.

## Python3

 # Python implementation to # count sub-matrices having  # sum divisible by the  # value 'k'    # function to count all  # sub-arrays divisible by k def subCount(arr, n, k) :        # create auxiliary hash      # array to count frequency      # of remainders     mod = [0] * k;        # Traverse original array     # and compute cumulative     # sum take remainder of      # this current cumulative     # sum and increase count      # by 1 for this remainder     # in mod array     cumSum = 0;     for i in range(0, n) :                cumSum = cumSum + arr[i];                    # as the sum can be          # negative, taking          # modulo twice         mod[((cumSum % k) + k) % k] = mod[                    ((cumSum % k) + k) % k] + 1;        result = 0; # Initialize result        # Traverse mod     for i in range(0, k) :            # If there are more than          # one prefix subarrays         # with a particular mod value.         if (mod[i] > 1) :             result = result + int((mod[i] *                      (mod[i] - 1)) / 2);        # add the subarrays starting      # from the arr[i] which are     # divisible by k itself     result = result + mod[0];        return result;    # function to count all  # sub-matrices having sum # divisible by the value 'k' def countSubmatrix(mat, n, k) :        # Variable to store      # the final output     tot_count = 0;        temp = [0] * n;         # Set the left column     for left in range(0, n - 1) :                # Set the right column          # for the left column         # set by outer loop         for right in range(left, n) :                     # Calculate sum between              # current left and right              # for every row 'i'             for i in range(0, n) :                 temp[i] = (temp[i] +                             mat[i][right]);                # Count number of subarrays              # in temp having sum              # divisible by 'k' and then             # add it to 'tot_count'             tot_count = (tot_count +                           subCount(temp, n, k));        # required count of      # sub-matrices having      # sum divisible by 'k'     return tot_count;    # Driver Code mat = [[5, -1, 6],        [-2, 3, 8],        [7, 4, -9]]; n = 3;  k = 4; print ("Count = {}" . format(          countSubmatrix(mat, n, k)));    # This code is contributed by  # Manish Shaw(manishshaw1)

## C#

 // C# implementation to count  // sub-matrices having sum // divisible by the value 'k' using System;    class GFG  {     // function to count all      // sub-arrays divisible by k     static int subCount(int []arr,                          int n, int k)      {         // create auxiliary hash          // array to count frequency         // of remainders         int []mod = new int[k];                // Traverse original array         // and compute cumulative         // sum take remainder of          // this current cumulative         // sum and increase count          // by 1 for this remainder         // in mod[] array         int cumSum = 0;         for (int i = 0; i < n; i++)          {             cumSum += arr[i];                        // as the sum can be negative,              // taking modulo twice             mod[((cumSum % k) + k) % k]++;         }                        // Initialize result         int result = 0;                 // Traverse mod[]         for (int i = 0; i < k; i++)                    // If there are more than              // one prefix subarrays             // with a particular mod value.             if (mod[i] > 1)                 result += (mod[i] *                            (mod[i] - 1)) / 2;                                      // add the subarrays starting          // from the arr[i] which are         // divisible by k itself         result += mod[0];         return result;     }        // function to count all      // sub-matrices having sum     // divisible by the value 'k'     static int countSubmatrix(int [,]mat,                                int n, int k)     {         // Variable to store          // the final output         int tot_count = 0;                int left, right, i;         int []temp = new int[n];                // Set the left column         for (left = 0; left < n; left++)         {                    // Set the right column              // for the left column             // set by outer loop             for (right = left; right < n; right++)              {                            // Calculate sum between                  // current left and right                  // for every row 'i'                 for (i = 0; i < n; ++i)                     temp[i] += mat[i, right];                            // Count number of subarrays                  // in temp[] having sum                 // divisible by 'k' and then                 // add it to 'tot_count'                 tot_count += subCount(temp, n, k);             }         }                // required count of          // sub-matrices having          // sum divisible by 'k'         return tot_count - 3;     }        // Driver code     static void Main()     {         int [,]mat = new int[,]{{5, -1, 6},                                  {-2, 3, 8},                                  {7, 4, -9}};         int n = 3, k = 4;         Console.Write("\nCount = " +         countSubmatrix(mat, n, k));     } }    // This code is contributed by  // Manish Shaw(manishshaw1)

## PHP

 1)             \$result += (\$mod[\$i] *                         (\$mod[\$i] - 1)) / 2;        // add the subarrays starting      // from the arr[i] which are     // divisible by k itself     \$result += \$mod[0];        return \$result; }    // function to count all  // sub-matrices having sum // divisible by the value 'k' function countSubmatrix(\$mat, \$n, \$k) {     // Variable to store      // the final output     \$tot_count = 0;        \$temp = array();         // Set the left column     for (\$left = 0;           \$left < \$n; \$left++)     {            // Initialize all          // elements of temp as 0         for(\$i = 0; \$i < \$n; \$i++)             \$temp[\$i] = 0;            // Set the right column          // for the left column         // set by outer loop         for (\$right = \$left;               \$right < \$n; \$right++)          {                // Calculate sum between              // current left and right              // for every row 'i'             for (\$i = 0; \$i < \$n; ++\$i)                 \$temp[\$i] += \$mat[\$i][\$right];                // Count number of subarrays              // in temp having sum               // divisible by 'k' and then             // add it to 'tot_count'             \$tot_count += subCount(\$temp, \$n, \$k);         }     }        // required count of      // sub-matrices having      // sum divisible by 'k'     return \$tot_count; }    // Driver Code \$mat = array(array(5, -1, 6),              array(-2, 3, 8),              array(7, 4, -9)); \$n = 3; \$k = 4; echo ("Count = " .         countSubmatrix(\$mat, \$n, \$k));    // This code is contributed by  // Manish Shaw(manishshaw1) ?>

Output:

Count = 6

Time Complexity: O(n^3).
Auxiliary Space: O(n).

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :