Sum of all Submatrices of a Given Matrix

Given a NxN 2-D matrix, the task to find the sum of all the submatrices.

Examples:

Input :  arr[] = {{1, 1},
                  {1, 1}};
Output : 16
Explanation: 
Number of sub-matrices with 1 elements = 4
Number of sub-matrices with 2 elements = 4
Number of sub-matrices with 3 elements = 0
Number of sub-matrices with 4 elements = 1

Since all the entries are 1, the sum becomes
sum = 1 * 4 + 2 * 4 + 3 * 0 + 4 * 1 = 16

Input : arr[] = {{1, 2, 3},
                 {4, 5, 6},
                 {7, 8, 9}}
Output : 500

Simple Solution: A naive solution is to generate all the possible submatrices, and sum up all of them.
The time complexity of this approach will be O(n6).

Efficient Solution : For each element of the matrix, let us try to find the number of sub-matrices, the element will lie in.
This can be done in O(1) time. Let us suppose the index of an element be (X, Y) in 0 based indexing, then the number of submatrices (Sx, y) for this element will be in can be given by the formula Sx, y = (X + 1) * (Y + 1) + (N – X) * (Y – X) . This formula works, because we just have to choose two different positions on the matrix that will create a submatrix that envelopes the element. Thus, for each element, ‘sum’ can be updated as sum += (Sx, y) * Arrx, y.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the sum of all
// possible submatrices of a given Matrix
  
#include <iostream>
#define n 3
using namespace std;
  
// Function to find the sum of all
// possible submatrices of a given Matrix
int matrixSum(int arr[][n])
{
    // Varialbe to store
    // the required sum
    int sum = 0;
  
    // Nested loop to find the number 
    // of submatrices, each number belongs to
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
  
            // Number of ways to choose
            // from top-left elements
            int top_left = (i + 1) * (j + 1);
  
            // Number of ways to choose
            // from bottom-right elements
            int bottom_right = (n - i) * (n - j);
            sum += (top_left * bottom_right * arr[i][j]);
        }
  
    return sum;
}
  
// Driver Code
int main()
{
    int arr[][n] = { { 1, 1, 1 },
                     { 1, 1, 1 },
                     { 1, 1, 1 } };
  
    cout << matrixSum(arr);
  
    return 0;
}

chevron_right


Output:

100


My Personal Notes arrow_drop_up