# XOR of a submatrix queries

Given an N * N matrix and q queries, each containing position of top-left and bottom-right corner of a rectangular sub-matrix, the task is to find the xor of all the elements from this sub-matrix.

Examples:

Input: arr[][] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, q[] = {{1, 1, 2, 2}, {1, 2, 2, 2}}
Output:
2
15
Query 1: 5 ^ 6 ^ 8 ^ 9 = 2
Query 2: 6 ^ 9 = 15

Input: arr[][] = {{21, 2}, { 14, 5}}, q[] = {{0, 1, 1, 1}, {0, 0, 1, 1}}
Output:
7
28

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

A simple solution is to find the XOR of the entire sub-matrix for each query. Thus, the worst case time complexity for each query will be O(n2).

Efficient Approach: We are all familiar with the idea of prefix XOR on linear array i.e.

if arr[] = {1, 2, 3, 4} and we calculate prefixXOR[] = {1, 3, 0, 4} where prefixXOR[i] stores the XOR of values from arr[0] to arr[i]
Then the XOR of sub-array arr[i] to arr[j] can be found as prefixXOR[j] ^ prefixXOR[i – 1]
For example, the XOR of sub-array {2, 3} will be XOR(0, 1) = 1
This is because in the prefixXOR values for {1, 2, 3} and {1}, the value 1 got repeated twice which will give 0 as the XOR result and will not affect the value of the other XOR operations.

We will try to extend the same to the 2-D matrix. We will compute a prefix-XOR matrix which will help us in solving each query in O(1).
In this case, our prefix-XOR matrix at position (R, C) will store the XOR of the rectangular sub-matrix with top-left corner at(0, 0) and bottom-right corner at (R, C).
We calculate the prefix-XOR in two steps.

1. Calculate the prefix-XOR for each row of the original matrix from left to right.
2. On the above matrix, calculate the prefix XOR for each column from top to bottom.

Once, we have the required prefix XOR-matrix, we can answer the queries with simplicity. XOR of a sub-matrix from (R1, C1) to (R2, C2) can be computed as prefix_xor[R2][C2] ^ prefix_xor[R1 – 1][C2] ^ prefix_xor[R2][C1 – 1] ^ prefix_xor[R1 – 1][C1 – 1].

Note: If R1 or C1 equals 0, then R1 – 1 or C1 – 1 should also be 0.

Below is the implementation of the above approach:

 `// C++ implementation of the approach ` `#include ` `#define n 3 ` `using` `namespace` `std; ` ` `  `// Function to pre-compute the xor ` `void` `preComputeXor(``int` `arr[][n], ``int` `prefix_xor[][n]) ` `{ ` `    ``// Left to right prefix xor ` `    ``// for each row ` `    ``for` `(``int` `i = 0; i < n; i++) ` `        ``for` `(``int` `j = 0; j < n; j++) { ` `            ``if` `(j == 0) ` `                ``prefix_xor[i][j] = arr[i][j]; ` `            ``else` `                ``prefix_xor[i][j] ` `                    ``= (prefix_xor[i][j - 1] ^ arr[i][j]); ` `        ``} ` ` `  `    ``// Top to bottom prefix xor ` `    ``// for each column ` `    ``for` `(``int` `i = 0; i < n; i++) ` `        ``for` `(``int` `j = 1; j < n; j++) ` `            ``prefix_xor[j][i] ` `                ``= (prefix_xor[j - 1][i] ^ prefix_xor[j][i]); ` `} ` ` `  `// Function to process the queries ` `// x1, x2, y1, y2 represent the ` `// positions of the top-left ` `// and bottom right corners ` `int` `ansQuerie(``int` `prefix_xor[][n], ``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2) ` `{ ` ` `  `    ``// To store the xor values ` `    ``int` `xor_1 = 0, xor_2 = 0, xor_3 = 0; ` ` `  `    ``// Finding the values we need to xor ` `    ``// with value at (x2, y2) in prefix-xor ` `    ``// matrix ` `    ``if` `(x1 != 0) ` `        ``xor_1 = prefix_xor[x1 - 1][y2]; ` `    ``if` `(y1 != 0) ` `        ``xor_2 = prefix_xor[x2][y1 - 1]; ` `    ``if` `(x1 != 0 and y1 != 0) ` `        ``xor_3 = prefix_xor[x1 - 1][y1 - 1]; ` ` `  `    ``// Return the required prefix xor ` `    ``return` `((prefix_xor[x2][y2] ^ xor_1) ^ (xor_2 ^ xor_3)); ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``int` `arr[][n] = { { 1, 2, 3 }, ` `                     ``{ 4, 5, 6 }, ` `                     ``{ 7, 8, 9 } }; ` ` `  `    ``// To store pre-computed xor ` `    ``int` `prefix_xor[n][n]; ` ` `  `    ``// Pre-computing xor ` `    ``preComputeXor(arr, prefix_xor); ` ` `  `    ``// Queries ` `    ``cout << ansQuerie(prefix_xor, 1, 1, 2, 2) << endl; ` `    ``cout << ansQuerie(prefix_xor, 1, 2, 2, 2) << endl; ` `    ``return` `0; ` `} `

 `// Java implementation of the approach  ` `class` `GfG ` `{ ` `     `  `static` `int` `n = ``3``; ` ` `  `// Function to pre-compute the xor  ` `static` `void` `preComputeXor(``int` `arr[][],  ` `                            ``int` `prefix_xor[][])  ` `{  ` `    ``// Left to right prefix xor  ` `    ``// for each row  ` `    ``for` `(``int` `i = ``0``; i < n; i++)  ` `        ``for` `(``int` `j = ``0``; j < n; j++)  ` `        ``{  ` `            ``if` `(j == ``0``)  ` `                ``prefix_xor[i][j] = arr[i][j];  ` `            ``else` `                ``prefix_xor[i][j] =  ` `                    ``(prefix_xor[i][j - ``1``] ^ arr[i][j]);  ` `        ``}  ` ` `  `    ``// Top to bottom prefix xor  ` `    ``// for each column  ` `    ``for` `(``int` `i = ``0``; i < n; i++)  ` `        ``for` `(``int` `j = ``1``; j < n; j++)  ` `            ``prefix_xor[j][i] =  ` `                ``(prefix_xor[j - ``1``][i] ^ prefix_xor[j][i]);  ` `}  ` ` `  `// Function to process the queries  ` `// x1, x2, y1, y2 represent the  ` `// positions of the top-left  ` `// and bottom right corners  ` `static` `int` `ansQuerie(``int` `prefix_xor[][], ``int` `x1,  ` `                    ``int` `y1, ``int` `x2, ``int` `y2)  ` `{  ` ` `  `    ``// To store the xor values  ` `    ``int` `xor_1 = ``0``, xor_2 = ``0``, xor_3 = ``0``;  ` ` `  `    ``// Finding the values we need to xor  ` `    ``// with value at (x2, y2) in prefix-xor  ` `    ``// matrix  ` `    ``if` `(x1 != ``0``)  ` `        ``xor_1 = prefix_xor[x1 - ``1``][y2];  ` `    ``if` `(y1 != ``0``)  ` `        ``xor_2 = prefix_xor[x2][y1 - ``1``];  ` `    ``if` `(x1 != ``0` `&& y1 != ``0``)  ` `        ``xor_3 = prefix_xor[x1 - ``1``][y1 - ``1``];  ` ` `  `    ``// Return the required prefix xor  ` `    ``return` `((prefix_xor[x2][y2] ^ xor_1) ^ (xor_2 ^ xor_3));  ` `}  ` ` `  `// Driver code  ` `public` `static` `void` `main(String[] args)  ` `{  ` `    ``int` `arr[][] = ``new` `int``[][]{{ ``1``, ``2``, ``3` `}, ` `                            ``{ ``4``, ``5``, ``6` `},  ` `                            ``{ ``7``, ``8``, ``9` `}};  ` ` `  `    ``// To store pre-computed xor  ` `    ``int` `prefix_xor[][] = ``new` `int``[n][n];  ` ` `  `    ``// Pre-computing xor  ` `    ``preComputeXor(arr, prefix_xor);  ` ` `  `    ``// Queries  ` `    ``System.out.println(ansQuerie(prefix_xor, ``1``, ``1``, ``2``, ``2``));  ` `    ``System.out.println(ansQuerie(prefix_xor, ``1``, ``2``, ``2``, ``2``));  ` `}  ` `}  ` ` `  `// This code is contributed by  ` `// Prerna Saini. `

 `n ``=` `3` ` `  `# Function to pre-compute the xor ` `def` `preComputeXor(arr, prefix_xor): ` `     `  `    ``# Left to right prefix xor ` `    ``# for each row ` `    ``for` `i ``in` `range``(n): ` `        ``for` `j ``in` `range``(n): ` `            ``if` `(j ``=``=` `0``): ` `                ``prefix_xor[i][j] ``=` `arr[i][j] ` `            ``else``: ` `                ``prefix_xor[i][j] ``=` `(prefix_xor[i][j ``-` `1``] ^  ` `                                               ``arr[i][j]) ` ` `  `    ``# Top to bottom prefix xor ` `    ``# for each column ` `    ``for` `i ``in` `range``(n): ` `        ``for` `j ``in` `range``(``1``, n): ` `            ``prefix_xor[j][i] ``=` `(prefix_xor[j ``-` `1``][i] ^  ` `                                    ``prefix_xor[j][i]) ` ` `  `# Function to process the queries ` `# x1, x2, y1, y2 represent the ` `# positions of the top-left ` `# and bottom right corners ` `def` `ansQuerie(prefix_xor, x1, y1, x2, y2): ` ` `  `    ``# To store the xor values ` `    ``xor_1, xor_2, xor_3 ``=` `0``, ``0``, ``0` ` `  `    ``# Finding the values we need to xor ` `    ``# with value at (x2, y2) in prefix-xor ` `    ``# matrix ` `    ``if` `(x1 !``=` `0``): ` `        ``xor_1 ``=` `prefix_xor[x1 ``-` `1``][y2] ` `    ``if` `(y1 !``=` `0``): ` `        ``xor_2 ``=` `prefix_xor[x2][y1 ``-` `1``] ` `    ``if` `(x1 !``=` `0` `and` `y1 !``=` `0``): ` `        ``xor_3 ``=` `prefix_xor[x1 ``-` `1``][y1 ``-` `1``] ` ` `  `    ``# Return the required prefix xor ` `    ``return` `((prefix_xor[x2][y2] ^ xor_1) ^  ` `                         ``(xor_2 ^ xor_3)) ` ` `  ` `  `# Driver code ` `arr ``=` `[[ ``1``, ``2``, ``3` `], ` `       ``[ ``4``, ``5``, ``6` `], ` `       ``[ ``7``, ``8``, ``9` `]] ` ` `  `# To store pre-computed xor ` `prefix_xor ``=` `[[``0` `for` `i ``in` `range``(n)] ` `                 ``for` `i ``in` `range``(n)] ` ` `  `# Pre-computing xor ` `preComputeXor(arr, prefix_xor) ` ` `  `# Queries ` `print``(ansQuerie(prefix_xor, ``1``, ``1``, ``2``, ``2``)) ` `print``(ansQuerie(prefix_xor, ``1``, ``2``, ``2``, ``2``)) ` ` `  `# This code is contributed by Mohit Kumar `

 `// C# implementation of the approach  ` `using` `System; ` ` `  `class` `GfG  ` `{  ` `    ``static` `int` `n = 3;  ` `     `  `    ``// Function to pre-compute the xor  ` `    ``static` `void` `preComputeXor(``int` `[,]arr,  ` `                                ``int` `[,]prefix_xor)  ` `    ``{  ` `        ``// Left to right prefix xor  ` `        ``// for each row  ` `        ``for` `(``int` `i = 0; i < n; i++)  ` `            ``for` `(``int` `j = 0; j < n; j++)  ` `            ``{  ` `                ``if` `(j == 0)  ` `                    ``prefix_xor[i, j] = arr[i, j];  ` `                ``else` `                    ``prefix_xor[i, j] =  ` `                   ``(prefix_xor[i, j - 1] ^ arr[i, j]);  ` `            ``}  ` `     `  `        ``// Top to bottom prefix xor  ` `        ``// for each column  ` `        ``for` `(``int` `i = 0; i < n; i++)  ` `            ``for` `(``int` `j = 1; j < n; j++)  ` `                ``prefix_xor[j, i] =  ` `                    ``(prefix_xor[j - 1, i] ^  ` `                     ``prefix_xor[j, i]);  ` `    ``}  ` `     `  `    ``// Function to process the queries  ` `    ``// x1, x2, y1, y2 represent the  ` `    ``// positions of the top-left  ` `    ``// and bottom right corners  ` `    ``static` `int` `ansQuerie(``int` `[,]prefix_xor, ``int` `x1,  ` `                         ``int` `y1, ``int` `x2, ``int` `y2)  ` `    ``{  ` `     `  `        ``// To store the xor values  ` `        ``int` `xor_1 = 0, xor_2 = 0, xor_3 = 0;  ` `     `  `        ``// Finding the values we need to xor  ` `        ``// with value at (x2, y2) in prefix-xor  ` `        ``// matrix  ` `        ``if` `(x1 != 0)  ` `            ``xor_1 = prefix_xor[x1 - 1, y2];  ` `        ``if` `(y1 != 0)  ` `            ``xor_2 = prefix_xor[x2, y1 - 1];  ` `        ``if` `(x1 != 0 && y1 != 0)  ` `            ``xor_3 = prefix_xor[x1 - 1, y1 - 1];  ` `     `  `        ``// Return the required prefix xor  ` `        ``return` `((prefix_xor[x2,y2] ^ xor_1) ^  ` `                            ``(xor_2 ^ xor_3));  ` `    ``}  ` `     `  `    ``// Driver code  ` `    ``public` `static` `void` `Main()  ` `    ``{  ` `        ``int` `[,]arr = {{ 1, 2, 3 },  ` `                      ``{ 4, 5, 6 }, ` `                      ``{ 7, 8, 9 }};  ` `     `  `        ``// To store pre-computed xor  ` `        ``int` `[,]prefix_xor = ``new` `int``[n, n];  ` `     `  `        ``// Pre-computing xor  ` `        ``preComputeXor(arr, prefix_xor);  ` `     `  `        ``// Queries  ` `        ``Console.WriteLine(ansQuerie(prefix_xor, 1, 1, 2, 2));  ` `        ``Console.WriteLine(ansQuerie(prefix_xor, 1, 2, 2, 2));  ` `    ``}  ` `}  ` ` `  `// This code is contributed by Ryuga `

 ` `

Output:
```2
15
```

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.

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.