Count sub-matrices having sum divisible 'k'
Last Updated :
08 Mar, 2024
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 <bits/stdc++.h>
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
<?php
// PHP implementation to
// count sub-matrices having
// sum divisible by the
// value 'k'
// function to count all
// sub-arrays divisible by k
function subCount($arr, $n, $k)
{
// create auxiliary hash
// array to count frequency
// of remainders
$mod = array();
for($i = 0; $i < $k; $i++)
$mod[$i] = 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
$cumSum = 0;
for ($i = 0; $i < $n; $i++)
{
$cumSum += $arr[$i];
// as the sum can be
// negative, taking
// modulo twice
$mod[(($cumSum % $k) +
$k) % $k]++;
}
$result = 0; // Initialize result
// Traverse mod
for ($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'
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
<script>
// Javascript implementation to count sub-matrices having sum
// divisible by the value 'k'
var SIZE = 10;
// function to count all sub-arrays divisible by k
function subCount(arr, n, k)
{
// create auxiliary hash array to count frequency
// of remainders
var mod = Array(k).fill(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
var cumSum = 0;
for (var i = 0; i < n; i++) {
cumSum += arr[i];
// as the sum can be negative, taking modulo
// twice
mod[((cumSum % k) + k) % k]++;
}
var result = 0; // Initialize result
// Traverse mod[]
for (var 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'
function countSubmatrix(mat, n, k)
{
// Variable to store the final output
var tot_count = 0;
var left, right, i;
var temp = Array(n);
// Set the left column
for (left = 0; left < n; left++) {
// Initialize all elements of temp as 0
temp = Array(n).fill(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 program to test above
var mat = [[5, -1, 6 ],
[-2, 3, 8 ],
[7, 4, -9 ]];
var n = 3, k = 4;
document.write( "Count = "
+ countSubmatrix(mat, n, k));
// This code is contributed by rrrtnx.
</script>
Time Complexity: O(n^3).
Auxiliary Space: O(n).
Similar Reads
Count subsets having product divisible by K Given an array arr[] of size N and an integer K, the task is to count the number of subsets from the given array with the product of elements divisible by K Examples: Input: arr[] = {1, 2, 3, 4, 5}, K = 60Output: 4Explanation: Subsets whose product of elements is divisible by K(= 60) are { {1, 2, 3,
9 min read
Largest rectangular sub-matrix having sum divisible by k Given a n x n matrix of integers. The problem is to find the largest area rectangular sub-matrix having sum divisible by the given value k. Examples: Input : mat[][] = { {1, 2, -1, -4} {-8, -3, 4, 2}, {3, 8, 10, 1} {-4, -1, 1, 7} } k = 5Output : Area = 12Explanation: (Top, Left): (0, 0) (Bottom, Rig
15+ min read
Count number of pairs in array having sum divisible by K | SET 2 Given an array A[] and positive integer K, the task is to count the total number of pairs in the array whose sum is divisible by K.Examples: Input : A[] = {2, 2, 1, 7, 5, 3}, K = 4 Output : 5 There are five pairs possible whose sum Is divisible by '4' i.e., (2, 2), (1, 7), (7, 5), (1, 3) and (5, 3)I
6 min read
Count paths whose sum is not divisible by K in given Matrix Given an integer matrix mat[][] of size M x N and an integer K, the task is to return the number of paths from top-left to bottom-right by moving only right and downwards such that the sum of the elements on the path is not divisible by K. Examples: Input: mat = [[5, 2, 4], [3, 0, 5], [0, 7, 2]], K
12 min read
Count pairs in array whose sum is divisible by K Given an array A[] and positive integer K, the task is to count the total number of pairs in the array whose sum is divisible by K. Note: This question is a generalized version of this Examples: Input : A[] = {2, 2, 1, 7, 5, 3}, K = 4 Output : 5 Explanation : There are five pairs possible whose sum
10 min read
Count Subarrays having Sum K Given an unsorted array of integers, the task is to find the number of subarrays having a sum exactly equal to a given number k.Examples: Input : arr[] = [10, 2, -2, -20, 10], k = -10Output : 3Explanation: Subarrays: arr[0...3], arr[1...4], arr[3...4] have sum equal to -10.Input : arr[] = [9, 4, 20,
8 min read
Count sub-arrays whose product is divisible by k Given an integer K and an array arr[], the task is to count all the sub-arrays whose product is divisible by K.Examples: Input: arr[] = {6, 2, 8}, K = 4 Output: 4 Required sub-arrays are {6, 2}, {6, 2, 8}, {2, 8}and {8}.Input: arr[] = {9, 1, 14}, K = 6 Output: 1 Naive approach: Run nested loops and
15+ min read
Count Subarrays With Sum Divisible By K Given an array arr[] and an integer k, the task is to count all subarrays whose sum is divisible by k.Examples: Input: arr[] = [4, 5, 0, -2, -3, 1], k = 5Output: 7Explanation: There are 7 subarrays whose sum is divisible by 5: [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3] and [
9 min read
Count Number of Divisible Triplet Sums Given a 0-indexed integer array arr[] and an integer d, return the count number of triplets (i, j, k) such that i < j < k and (arr[i] + arr[j] + arr[k]) % d == 0. Example: Input: arr= [3,3,4,7,8], d = 5Output: 3Explanation: The triplets which are divisible by 5 are: (0, 1, 2), (0, 2, 4), (1, 2
14 min read
Count pairs in Array whose product is divisible by K Given a array vec and an integer K, count the number of pairs (i, j) such that vec[i]*vec[j] is divisible by K where i<j. Examples: Input: vec = {1, 2, 3, 4, 5, 6}, K = 4Output: 6Explanation: The pairs of indices (0, 3), (1, 3), (2, 3), (3, 4), (3, 5) and (1, 5) satisfy the condition as their pro
11 min read