# Queries to count minimum flips required to fill a binary submatrix with 0s only

• Last Updated : 01 Jun, 2021

Given a binary matrix mat[][] of size M * N and Q queries of the form {pi, pj, qi, qj}, the task for each query is to count the number of 0s in the submatrix from the cell (pi, pj) to (qi, qj).

Examples:

Input: mat[][] = {{0, 1, 0, 1, 1, 1, 0}, {1, 0, 1, 1, 1, 0, 1}, {1, 1, 0, 0, 1, 1, 0}, {1, 1, 1, 1, 1, 0, 1}, {0, 0, 1, 0, 1, 1, 1}, {1, 1, 0, 1, 1, 0, 1 }}, Q[] = {{0, 1, 3, 2}, {2, 2, 4, 5}, {4, 3, 5, 6}}
Output: 3 4 2
Explanation:
The submatrix from indices (0, 1) to (3, 2) contains 3 0s.
The submatrix from indices (2, 2) to (4, 5) contains 4 0s.
The submatrix from indices (4, 3) to (5, 6) contains 2 0s.

Input: mat[][] = {{0, 1, 0}, {1, 0, 1}}, Q[] = {{0, 0, 2, 2}}
Output: 3

Naive Approach: The simplest approach to solve the problem is to count the number of 0s for each query by iterating the submatrix and print the count for each query.

Time Complexity: O(M*N*Q)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to preprocess the given matrix mat[][]. Create a count matrix, say prefixCnt[M][N], such that prefix_cnt[i][j] stores the count of 0s in the submatrix within indices (0, 0) to (i, j). Follow the steps below to compute prefixCnt[][]:

• Initialize prefixCnt[i][j] with 1 if mat[i][j] is 0. Otherwise, initialize with 0.
• Find the prefix sum for each row and column and update the matrix accordingly.

Once, matrix prefixCnt[][] is computed the count of 0s in any sub-matrix can be evaluated in O(1) time. Below is the expression to count the 0s in each submatrix from (pi, pj) to (qi, qj) can be calculated by:

cnt = prefixCnt[qi][qj] – prefixCnt[pi-1][qj] – prefixCnt[qi][pj – 1] + prefixCnt[pi – 1][pj – 1]

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `#define M 6``#define N 7` `// Function to compute the matrix``// prefixCnt[M][N] from mat[M][N] such``// that prefixCnt[i][j] stores the``// count of 0's from (0, 0) to (i, j)``void` `preCompute(``int` `mat[M][N],``                ``int` `prefixCnt[M][N])``{``    ``for` `(``int` `i = 0; i < M; i++) {` `        ``for` `(``int` `j = 0; j < N; j++) {` `            ``// Initialize prefixCnt[i][j]``            ``// with 1 if mat[i][j] is 0``            ``if` `(mat[i][j] == 0) {``                ``prefixCnt[i][j] = 1;``            ``}` `            ``// Otherwise, assign with 0``            ``else` `{``                ``prefixCnt[i][j] = 0;``            ``}``        ``}``    ``}` `    ``// Calculate prefix sum for each row``    ``for` `(``int` `i = 0; i < M; i++)``        ``for` `(``int` `j = 1; j < N; j++)``            ``prefixCnt[i][j] += prefixCnt[i][j - 1];` `    ``// Calculate prefix sum for each column``    ``for` `(``int` `i = 1; i < M; i++)``        ``for` `(``int` `j = 0; j < N; j++)``            ``prefixCnt[i][j] += prefixCnt[i - 1][j];``}` `// Function to compute count of 0's``// in submatrix from (pi, pj) to``// (qi, qj) from prefixCnt[M][N]``int` `countQuery(``int` `prefixCnt[M][N],``               ``int` `pi, ``int` `pj,``               ``int` `qi, ``int` `qj)``{``    ``// Initialize that count of 0's``    ``// in the sub-matrix within``    ``// indices (0, 0) to (qi, qj)``    ``int` `cnt = prefixCnt[qi][qj];` `    ``// Subtract count of 0's within``    ``// indices (0, 0) and (pi-1, qj)``    ``if` `(pi > 0)``        ``cnt -= prefixCnt[pi - 1][qj];` `    ``// Subtract count of 0's within``    ``// indices (0, 0) and (qi, pj-1)``    ``if` `(pj > 0)``        ``cnt -= prefixCnt[qi][pj - 1];` `    ``// Add prefixCnt[pi - 1][pj - 1]``    ``// because its value has been added``    ``// once but subtracted twice``    ``if` `(pi > 0 && pj > 0)``        ``cnt += prefixCnt[pi - 1][pj - 1];` `    ``return` `cnt;``}` `// Function to count the 0s in the``// each given submatrix``void` `count0s(``int` `mat[M][N], ``int` `Q[][4],``             ``int` `sizeQ)``{` `    ``// Stores the prefix sum of each``    ``// row and column``    ``int` `prefixCnt[M][N];` `    ``// Compute matrix prefixCnt[][]``    ``preCompute(mat, prefixCnt);` `    ``for` `(``int` `i = 0; i < sizeQ; i++) {` `        ``// Function Call for each query``        ``cout << countQuery(prefixCnt, Q[i][0],``                           ``Q[i][1], Q[i][2],``                           ``Q[i][3])``             ``<< ``' '``;``    ``}``}` `// Driver Code``int` `main()``{``    ``// Given matrix``    ``int` `mat[M][N] = {``        ``{ 0, 1, 0, 1, 1, 1, 0 },``        ``{ 1, 0, 1, 1, 1, 0, 1 },``        ``{ 1, 1, 0, 0, 1, 1, 0 },``        ``{ 1, 1, 1, 1, 1, 0, 1 },``        ``{ 0, 0, 1, 0, 1, 1, 1 },``        ``{ 1, 1, 0, 1, 1, 0, 1 }``    ``};` `    ``int` `Q[][4] = { { 0, 1, 3, 2 },``                   ``{ 2, 2, 4, 5 },``                   ``{ 4, 3, 5, 6 } };` `    ``int` `sizeQ = ``sizeof``(Q) / ``sizeof``(Q[0]);` `    ``// Function Call``    ``count0s(mat, Q, sizeQ);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``class` `GFG{``    ` `final` `static` `int` `M = ``6``;``final` `static` `int` `N  = ``7``;` `// Function to compute the matrix``// prefixCnt[M][N] from mat[M][N] such``// that prefixCnt[i][j] stores the``// count of 0's from (0, 0) to (i, j)``static` `void` `preCompute(``int` `mat[][], ``int` `prefixCnt[][])``{``    ``for``(``int` `i = ``0``; i < M; i++)``    ``{``        ``for``(``int` `j = ``0``; j < N; j++)``        ``{``            ` `            ``// Initialize prefixCnt[i][j]``            ``// with 1 if mat[i][j] is 0``            ``if` `(mat[i][j] == ``0``)``            ``{``                ``prefixCnt[i][j] = ``1``;``            ``}` `            ``// Otherwise, assign with 0``            ``else``            ``{``                ``prefixCnt[i][j] = ``0``;``            ``}``        ``}``    ``}` `    ``// Calculate prefix sum for each row``    ``for``(``int` `i = ``0``; i < M; i++)``        ``for``(``int` `j = ``1``; j < N; j++)``            ``prefixCnt[i][j] += prefixCnt[i][j - ``1``];` `    ``// Calculate prefix sum for each column``    ``for``(``int` `i = ``1``; i < M; i++)``        ``for``(``int` `j = ``0``; j < N; j++)``            ``prefixCnt[i][j] += prefixCnt[i - ``1``][j];``}` `// Function to compute count of 0's``// in submatrix from (pi, pj) to``// (qi, qj) from prefixCnt[M][N]``static` `int` `countQuery(``int` `prefixCnt[][],``                      ``int` `pi, ``int` `pj,``                      ``int` `qi, ``int` `qj)``{``    ` `    ``// Initialize that count of 0's``    ``// in the sub-matrix within``    ``// indices (0, 0) to (qi, qj)``    ``int` `cnt = prefixCnt[qi][qj];``    ` `    ``// Subtract count of 0's within``    ``// indices (0, 0) and (pi-1, qj)``    ``if` `(pi > ``0``)``        ``cnt -= prefixCnt[pi - ``1``][qj];` `    ``// Subtract count of 0's within``    ``// indices (0, 0) and (qi, pj-1)``    ``if` `(pj > ``0``)``        ``cnt -= prefixCnt[qi][pj - ``1``];` `    ``// Add prefixCnt[pi - 1][pj - 1]``    ``// because its value has been added;``    ``// once but subtracted twice``    ``if` `(pi > ``0` `&& pj > ``0``)``        ``cnt += prefixCnt[pi - ``1``][pj - ``1``];` `    ``return` `cnt;``}` `// Function to count the 0s in the``// each given submatrix``static` `void` `count0s(``int` `mat[][], ``int` `Q[][],``                    ``int` `sizeQ)``{``    ` `    ``// Stores the prefix sum of each``    ``// row and column``    ``int` `prefixCnt[][] = ``new` `int``[M][N];``    ` `    ``// Compute matrix prefixCnt[][]``    ``preCompute(mat, prefixCnt);` `    ``for``(``int` `i = ``0``; i < sizeQ; i++)``    ``{``        ` `        ``// Function Call for each query``        ``System.out.print(countQuery(prefixCnt, Q[i][``0``],``                                               ``Q[i][``1``],``                                               ``Q[i][``2``],``                                               ``Q[i][``3``]) + ``" "``);``    ``}``}` `// Driver Code``public` `static` `void` `main (String[] args)``{``    ` `    ``// Given matrix``    ``int` `mat[][] = { { ``0``, ``1``, ``0``, ``1``, ``1``, ``1``, ``0` `},``                    ``{ ``1``, ``0``, ``1``, ``1``, ``1``, ``0``, ``1` `},``                    ``{ ``1``, ``1``, ``0``, ``0``, ``1``, ``1``, ``0` `},``                    ``{ ``1``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1` `},``                    ``{ ``0``, ``0``, ``1``, ``0``, ``1``, ``1``, ``1` `},``                    ``{ ``1``, ``1``, ``0``, ``1``, ``1``, ``0``, ``1` `} };` `    ``int` `Q[][] = { { ``0``, ``1``, ``3``, ``2` `},``                  ``{ ``2``, ``2``, ``4``, ``5` `},``                  ``{ ``4``, ``3``, ``5``, ``6` `} };` `    ``int` `sizeQ = Q.length;` `    ``// Function Call``    ``count0s(mat, Q, sizeQ);``}``}` `// This code is contributed by AnkThon`

## Python3

 `# Python3 program for the above approach` `M ``=` `6``N ``=` `7` `# Function to compute the matrix``# prefixCnt[M][N] from mat[M][N] such``# that prefixCnt[i][j] stores the``# count of 0's from (0, 0) to (i, j)``def` `preCompute(mat, prefixCnt):``    ``for` `i ``in` `range``(M):` `        ``for` `j ``in` `range``(N):` `            ``# Initialize prefixCnt[i][j]``            ``# with 1 if mat[i][j] is 0``            ``if` `(mat[i][j] ``=``=` `0``):``                ``prefixCnt[i][j] ``=` `1``            ` `            ``# Otherwise, assign with 0``            ``else``:``                ``prefixCnt[i][j] ``=` `0` `    ``# Calculate prefix sum for each row``    ``for` `i ``in` `range``(M):``        ``for` `j ``in` `range``(``1``, N):``            ``prefixCnt[i][j] ``+``=` `prefixCnt[i][j ``-` `1``]` `    ``# Calculate prefix sum for each column``    ``for` `i ``in` `range``(``1``, M):``        ``for` `j ``in` `range``(N):``            ``prefixCnt[i][j] ``+``=` `prefixCnt[i ``-` `1``][j]``    ``return` `prefixCnt` `# Function to compute count of 0's``# in submatrix from (pi, pj) to``# (qi, qj) from prefixCnt[M][N]``def` `countQuery(prefixCnt, pi, pj, qi, qj):``    ` `    ``# Initialize that count of 0's``    ``# in the sub-matrix within``    ``# indices (0, 0) to (qi, qj)``    ``cnt ``=` `prefixCnt[qi][qj]` `    ``# Subtract count of 0's within``    ``# indices (0, 0) and (pi-1, qj)``    ``if` `(pi > ``0``):``        ``cnt ``-``=` `prefixCnt[pi ``-` `1``][qj]` `    ``# Subtract count of 0's within``    ``# indices (0, 0) and (qi, pj-1)``    ``if` `(pj > ``0``):``        ``cnt ``-``=` `prefixCnt[qi][pj ``-` `1``]` `    ``# Add prefixCnt[pi - 1][pj - 1]``    ``# because its value has been added``    ``# once but subtracted twice``    ``if` `(pi > ``0` `and` `pj > ``0``):``        ``cnt ``+``=` `prefixCnt[pi ``-` `1``][pj ``-` `1``]` `    ``return` `cnt` `# Function to count the 0s in the``# each given submatrix``def` `count0s(mat, Q, sizeQ):` `    ``# Stores the prefix sum of each``    ``# row and column``    ``prefixCnt ``=` `[[ ``0` `for` `i ``in` `range``(N)] ``for` `i ``in` `range``(M)]` `    ``# Compute matrix prefixCnt[][]``    ``prefixCnt ``=` `preCompute(mat, prefixCnt)` `    ``for` `i ``in` `range``(sizeQ):` `        ``# Function Call for each query``        ``print``(countQuery(prefixCnt, Q[i][``0``], Q[i][``1``], Q[i][``2``], Q[i][``3``]), end``=``" "``)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# Given matrix``    ``mat ``=` `[[ ``0``, ``1``, ``0``, ``1``, ``1``, ``1``, ``0` `],``        ``[ ``1``, ``0``, ``1``, ``1``, ``1``, ``0``, ``1` `],``        ``[ ``1``, ``1``, ``0``, ``0``, ``1``, ``1``, ``0` `],``        ``[ ``1``, ``1``, ``1``, ``1``, ``1``, ``0``, ``1` `],``        ``[ ``0``, ``0``, ``1``, ``0``, ``1``, ``1``, ``1` `],``        ``[ ``1``, ``1``, ``0``, ``1``, ``1``, ``0``, ``1` `] ]` `    ``Q``=` `[ [ ``0``, ``1``, ``3``, ``2` `],``        ``[ ``2``, ``2``, ``4``, ``5` `],``        ``[ ``4``, ``3``, ``5``, ``6` `] ]` `    ``sizeQ ``=` `len``(Q)` `    ``# Function Call``    ``count0s(mat, Q, sizeQ)` `    ``# This code is contributed by mohit kumar 29`

## C#

 `// C# program for the above approach``using` `System;``class` `GFG``{``    ` `static` `int` `M = 6;``static` `int` `N  = 7;` `// Function to compute the matrix``// prefixCnt[M][N] from mat[M][N] such``// that prefixCnt[i][j] stores the``// count of 0's from (0, 0) to (i, j)``static` `void` `preCompute(``int` `[,]mat, ``int` `[,]prefixCnt)``{``    ``for``(``int` `i = 0; i < M; i++)``    ``{``        ``for``(``int` `j = 0; j < N; j++)``        ``{``            ` `            ``// Initialize prefixCnt[i][j]``            ``// with 1 if mat[i,j] is 0``            ``if` `(mat[i, j] == 0)``            ``{``                ``prefixCnt[i, j] = 1;``            ``}` `            ``// Otherwise, assign with 0``            ``else``            ``{``                ``prefixCnt[i, j] = 0;``            ``}``        ``}``    ``}` `    ``// Calculate prefix sum for each row``    ``for``(``int` `i = 0; i < M; i++)``        ``for``(``int` `j = 1; j < N; j++)``            ``prefixCnt[i, j] += prefixCnt[i, j - 1];` `    ``// Calculate prefix sum for each column``    ``for``(``int` `i = 1; i < M; i++)``        ``for``(``int` `j = 0; j < N; j++)``            ``prefixCnt[i, j] += prefixCnt[i - 1, j];``}` `// Function to compute count of 0's``// in submatrix from (pi, pj) to``// (qi, qj) from prefixCnt[M][N]``static` `int` `countQuery(``int` `[,]prefixCnt,``                      ``int` `pi, ``int` `pj,``                      ``int` `qi, ``int` `qj)``{``    ` `    ``// Initialize that count of 0's``    ``// in the sub-matrix within``    ``// indices (0, 0) to (qi, qj)``    ``int` `cnt = prefixCnt[qi, qj];``    ` `    ``// Subtract count of 0's within``    ``// indices (0, 0) and (pi-1, qj)``    ``if` `(pi > 0)``        ``cnt -= prefixCnt[pi - 1, qj];` `    ``// Subtract count of 0's within``    ``// indices (0, 0) and (qi, pj-1)``    ``if` `(pj > 0)``        ``cnt -= prefixCnt[qi, pj - 1];` `    ``// Add prefixCnt[pi - 1][pj - 1]``    ``// because its value has been added;``    ``// once but subtracted twice``    ``if` `(pi > 0 && pj > 0)``        ``cnt += prefixCnt[pi - 1, pj - 1];` `    ``return` `cnt;``}` `// Function to count the 0s in the``// each given submatrix``static` `void` `count0s(``int` `[,]mat, ``int` `[,]Q,``                    ``int` `sizeQ)``{``    ` `    ``// Stores the prefix sum of each``    ``// row and column``    ``int` `[,]prefixCnt = ``new` `int``[M, N];``    ` `    ``// Compute matrix prefixCnt[,]``    ``preCompute(mat, prefixCnt);` `    ``for``(``int` `i = 0; i < sizeQ; i++)``    ``{``        ` `        ``// Function Call for each query``        ``Console.Write(countQuery(prefixCnt, Q[i, 0],``                                               ``Q[i, 1],``                                               ``Q[i, 2],``                                               ``Q[i, 3]) + ``" "``);``    ``}``}` `// Driver Code``public` `static` `void` `Main(``string``[] args)``{``    ` `    ``// Given matrix``    ``int` `[,]mat = { { 0, 1, 0, 1, 1, 1, 0 },``                    ``{ 1, 0, 1, 1, 1, 0, 1 },``                    ``{ 1, 1, 0, 0, 1, 1, 0 },``                    ``{ 1, 1, 1, 1, 1, 0, 1 },``                    ``{ 0, 0, 1, 0, 1, 1, 1 },``                    ``{ 1, 1, 0, 1, 1, 0, 1 } };` `    ``int` `[,]Q = { { 0, 1, 3, 2 },``                  ``{ 2, 2, 4, 5 },``                  ``{ 4, 3, 5, 6 } };` `    ``int` `sizeQ = Q.GetLength(0);` `    ``// Function Call``    ``count0s(mat, Q, sizeQ);``}``}` `// This code is contributed by AnkThon`

## Javascript

 ``

Output:

`3 4 2`

Time Complexity: O(M*N + Q)
Auxiliary Space: O(M*N)

My Personal Notes arrow_drop_up