Open in App
Not now

# Count sub-matrices having sum divisible ‘k’

• Difficulty Level : Hard
• Last Updated : 28 Jul, 2022

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)```

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.

Implementation:

## 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)` `?>`

## Javascript

 ``

Output

`Count = 6`

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

My Personal Notes arrow_drop_up
Related Articles