A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

Given a binary matrix **arr[][]** of dimensions **M x N** and **Q** queries of the form (**x1, y1, x2, y2)**, where (**x1, y1**) and (**x2, y2**) denotes the top-left and bottom-right indices of the submatrix required to be flipped(convert 0s to 1s and vice versa) respectively. The task is to print the final matrix obtained after performing given **Q** queries

**Examples:**

_ arr[][] = {{0, 1, 0}, {1, 1, 0}}, queries[][] = {{1, 1, 2, 3}}_Input:

_ [[1, 0, 1], [0, 0, 1]]_Output:

Explanation:

_The submatrix to be flipped is equal to {{0, 1, 0}, {1, 1, 0}} _

The flipped matrix is {{1, 0, 1}, {0, 0, 1}}.

_ arr[][] = {{0, 1, 0}, {1, 1, 0}}, queries[][] = {{1, 1, 2, 3}, {1, 1, 1, 1], {1, 2, 2, 3}}_Input:

_ [[0, 1, 0], [0, 1, 0]]_Output:

Explanation:

Query 1:

_Submatrix to be flipped = [[0, 1, 0], [1, 1, 0]] _

_Flipped submatrix is [[1, 0, 1], [0, 0, 1]]. _

Therefore, the modified matrix is [[1, 0, 1], [0, 0, 1]].

_Query 2: _

_Submatrix to be flipped = [[1]] _

_Flipped submatrix is [[0]] _

Therefore, matrix is [[0, 0, 1], [0, 0, 1]].

Query 3:

_Submatrix to be flipped = [[0, 1], [0, 1]] _

_Flipped submatrix is [[1, 0], [1, 0]] _

Therefore, modified matrix is [[0, 1, 0], [0, 1, 0]].

**Naive Approach:** The simplest approach to solve the problem for each query is to iterate over the given submatrices and for every element, check if it is 0 or 1, and flip accordingly. After completing these operations for all the queries, print the final matrix obtained.

Below is the implementation of the above approach :

- Python

`## Python Program to implement`

`## the above approach`

`## Function to flip a submatrices`

`**def**`

`manipulation(matrix, q):`

`## Boundaries of the submatrix`

`x1, y1, x2, y2`

`**=**`

`q`

`## Iterate over the submatrix`

`**for**`

`i`

`**in**`

`range``(x1``**-**``1``, x2):`

`**for**`

`j`

`**in**`

`range``(y1``**-**``1``, y2):`

`## Check for 1 or 0`

`## and flip accordingly`

`**if**`

`matrix[i][j]:`

`matrix[i][j]`

`**=**`

`0`

`**else**``:`

`matrix[i][j]`

`**=**`

`1`

`## Function to perform the queries`

`**def**`

`queries_fxn(matrix, queries):`

`**for**`

`q`

`**in**`

`queries:`

`manipulation(matrix, q)`

`## Driver Code`

`matrix`

`**=**`

`[[``0``,`

`1``,`

`0``], [``1``,`

`1``,`

`0``]]`

`queries`

`**=**`

`[[``1``,`

`1``,`

`2``,`

`3``], \`

`[``1``,`

`1``,`

`1``,`

`1``], \`

`[``1``,`

`2``,`

`2``,`

`3``]]`

`## Function call`

`queries_fxn(matrix, queries)`

`print``(matrix)`

**Output:**

`[[0, 1, 0], [0, 1, 0]]`

** Time complexity:**_ O( N * M * Q)_

** Auxiliary Space:**_ O(1)_

**Efficient Approach:** The above approach can be optimized using Dynamic programming and Prefix Sum technique. Mark the boundaries of the submatrices involved in each query and then calculate **prefix sum** of the operations involved in the matrix and update the matrix accordingly. Follow the steps below to solve the problem:

- Initialize a 2D state space table
**dp[][]**to store the count of flips at respective indices of the matrix - For each query {x1, y1, x2, y2, K}, update the dp[][] matrix by the following operations:
- dp[x1][y1] += 1
- dp[x2 + 1][y1] -= 1
- dp[x2 + 1][y2 + 1] += 1
- dp[x1][y2 + 1] -= 1

Now, traverse over the dp[][] matrix and update dp[i][j] by calculating prefix sum of the rows and colums and diagonals by the following relation:

dp[i][j] = dp[i][j] + dp[i-1][j] + dp[i][j – 1] – dp[i – 1][j – 1]

If dp[i][j] is found to be odd, reduce mat[i – 1][j – 1] by 1.

Finally print the updated matrix mat[][] as the result.

Below is the implementation of the above approach :

- Python

`## Python program to implement`

`## the above approach`

`## Function to modify dp[][] array by`

`## generating prefix sum`

`**def**`

`modifyDP(matrix, dp):`

`**for**`

`j`

`**in**`

`range``(``1``,`

`len``(matrix)``**+**``1``):`

`**for**`

`k`

`**in**`

`range``(``1``,`

`len``(matrix[``0``])``**+**``1``):`

`## Update the tabular data`

`dp[j][k]`

`**=**`

`dp[j][k]`

`**+**`

`dp[j``**-**``1``][k] \`

`**+**`

`dp[j][k``**-**``1``]``**-**``dp[j``**-**``1``][k``**-**``1``]`

`## If the count of flips is even`

`**if**`

`dp[j][k]`

`**%**`

`2`

`!``**=**`

`0``:`

`matrix[j``**-**``1``][k``**-**``1``]`

`**=**`

`int``(matrix[j``**-**``1``][k``**-**``1``]) ^`

`1`

`## Function to update dp[][] matrix`

`## for each query`

`**def**`

`queries_fxn(matrix, queries, dp):`

`**for**`

`q`

`**in**`

`queries:`

`x1, y1, x2, y2`

`**=**`

`q`

`## Update the table`

`dp[x1][y1]`

`**+=**`

`1`

`dp[x2`

`**+**`

`1``][y2`

`**+**`

`1``]`

`**+=**`

`1`

`dp[x1][y2`

`**+**`

`1``]`

`**-=**`

`1`

`dp[x2`

`**+**`

`1``][y1]`

`**-=**`

`1`

`modifyDP(matrix, dp)`

`## Driver Code`

`matrix`

`**=**`

`[[``0``,`

`1``,`

`0``], [``1``,`

`1``,`

`0``]]`

`queries`

`**=**`

`[[``1``,`

`1``,`

`2``,`

`3``], \`

`[``1``,`

`1``,`

`1``,`

`1``], \`

`[``1``,`

`2``,`

`2``,`

`3``]]`

`## Initialize dp table`

`dp`

`**=**`

`[[``0`

`**for**`

`i`

`**in**`

`range``(``len``(matrix[``0``])``**+**``2``)] \`

`**for**`

`j`

`**in**`

`range``(``len``(matrix)``**+**``2``)]`

`queries_fxn(matrix, queries, dp)`

`print``(matrix)`

**Output:**

`[[0, 1, 0], [0, 1, 0]]`

** Time Complexity:**_ O(N * M )_

** Auxiliary Space:**_ O(N * M)_

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.

bit magic dynamic programming hash mathematical matrix array-rearrange binary-representation prefix-sum submatrix

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.