Median of Bitwise XOR of all submatrices starting from the top left corner
Given a 2D matrix mat[][] of size N * M, the task is to find the median of Bitwise XOR of all possible submatrices from the given matrix having topmost left element at (0, 0).
Examples:
Input : M[][] = { { 1, 2 }, { 2, 3 } }
Output: 2.5
Explanation:
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (0, 0) is mat[0][0] = 1.
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (0, 1) is mat[0][0] ^ mat[0][1] = 3.
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (1, 0) is mat[0][0] ^ mat[1][0] = 3.
Bitwise XOR of submatrix whose topmost left corner is (0, 0) and bottommost right corner is (1, 1) is mat[0][0] ^ mat[1][0] ^ mat[0][1] ^ mat[1][1] = 2.
Median of bitwise XOR of all possible submatrix whose topmost left corner is (2 + 3) / 2 = 2.5.
Input : M[][] = { { 1, 5, 2 }, { 2, 3, 23 }, { 7, 43, 13 } }
Output: 5
Approach: The problem can be solved using Dynamic programming based on the following recurrence relation
dp[i][j] = dp[i – 1][j – 1] ^ dp[i][j – 1] ^ dp[i – 1][j] ^ mat[i][j]
mat[i][j]: Stores the Bitwise XOR of the submatrix whose topmost left corner is (0, 0) and bottom most right corner is (i, j).
Follow the steps below to solve the problem:
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
double findMedXOR( int mat[][2], int N, int M)
{
int dp[N][M];
int med[N * M];
dp[0][0] = mat[0][0];
med[0] = dp[0][0];
int len = 1;
for ( int i = 1; i < N; i++) {
dp[i][0]
= dp[i - 1][0] ^ mat[i][0];
med[len++] = dp[i][0];
}
for ( int i = 1; i < M; i++) {
dp[0][i]
= dp[0][i - 1] ^ mat[0][i];
med[len++] = dp[0][i];
}
for ( int i = 1; i < N; i++) {
for ( int j = 1; j < M; j++) {
dp[i][j] = dp[i - 1][j]
^ dp[i][j - 1]
^ dp[i - 1][j - 1]
^ mat[i][j];
med[len++] = dp[i][j];
}
}
sort(med, med + len);
if (len % 2 == 0) {
return (med[(len / 2)]
+ med[(len / 2) - 1])
/ 2.0;
}
return med[len / 2];
}
int main()
{
int mat[][2] = { { 1, 2 }, { 2, 3 } };
int N = sizeof (mat) / sizeof (mat[0]);
int M = 2;
cout << findMedXOR(mat, N, M);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static double findMedXOR( int mat[][], int N, int M)
{
int dp[][] = new int [N][M];
int med[] = new int [N * M];
dp[ 0 ][ 0 ] = mat[ 0 ][ 0 ];
med[ 0 ] = dp[ 0 ][ 0 ];
int len = 1 ;
for ( int i = 1 ; i < N; i++)
{
dp[i][ 0 ] = dp[i - 1 ][ 0 ] ^ mat[i][ 0 ];
med[len++] = dp[i][ 0 ];
}
for ( int i = 1 ; i < M; i++)
{
dp[ 0 ][i] = dp[ 0 ][i - 1 ] ^ mat[ 0 ][i];
med[len++] = dp[ 0 ][i];
}
for ( int i = 1 ; i < N; i++)
{
for ( int j = 1 ; j < M; j++)
{
dp[i][j] = dp[i - 1 ][j]
^ dp[i][j - 1 ]
^ dp[i - 1 ][j - 1 ]
^ mat[i][j];
med[len++] = dp[i][j];
}
}
Arrays.sort(med);
if (len % 2 == 0 )
{
return (med[(len / 2 )]
+ med[(len / 2 ) - 1 ])
/ 2.0 ;
}
return med[len / 2 ];
}
public static void main(String[] args)
{
int mat[][] = { { 1 , 2 }, { 2 , 3 } };
int N = mat.length;
int M = 2 ;
System.out.println(findMedXOR(mat, N, M));
}
}
|
Python3
def findMedXOR(mat, N, M):
dp = [[ 0 for i in range (M)] for j in range (N)];
med = [ 0 ] * (N * M);
dp[ 0 ][ 0 ] = mat[ 0 ][ 0 ];
med[ 0 ] = dp[ 0 ][ 0 ];
len = 1 ;
for i in range ( 1 , N):
dp[i][ 0 ] = dp[i - 1 ][ 0 ] ^ mat[i][ 0 ];
med[ len ] = dp[i][ 0 ];
len + = 1 ;
for i in range ( 1 , M):
dp[ 0 ][i] = dp[ 0 ][i - 1 ] ^ mat[ 0 ][i];
med[ len ] = dp[ 0 ][i];
len + = 1
for i in range ( 1 , N):
for j in range ( 1 , M):
dp[i][j] = dp[i - 1 ][j] ^ dp[i][j - 1 ] ^ dp[i - 1 ][j - 1 ] ^ mat[i][j];
med[ len ] = dp[i][j];
len + = 1
med.sort();
if ( len % 2 = = 0 ):
return (med[( len / / 2 )] + med[( len / / 2 ) - 1 ]) / 2.0 ;
return med[ len / / 2 ];
if __name__ = = '__main__' :
mat = [[ 1 , 2 ], [ 2 , 3 ]];
N = len (mat[ 0 ]);
M = 2 ;
print (findMedXOR(mat, N, M));
|
C#
using System;
class GFG
{
static double findMedXOR( int [,]mat, int N, int M)
{
int [,]dp = new int [N, M];
int []med = new int [N * M];
dp[0, 0] = mat[0, 0];
med[0] = dp[0, 0];
int len = 1;
for ( int i = 1; i < N; i++)
{
dp[i, 0] = dp[i - 1, 0] ^ mat[i, 0];
med[len++] = dp[i, 0];
}
for ( int i = 1; i < M; i++)
{
dp[0, i] = dp[0, i - 1] ^ mat[0, i];
med[len++] = dp[0, i];
}
for ( int i = 1; i < N; i++)
{
for ( int j = 1; j < M; j++)
{
dp[i, j] = dp[i - 1, j]
^ dp[i, j - 1]
^ dp[i - 1, j - 1]
^ mat[i, j];
med[len++] = dp[i, j];
}
}
Array.Sort(med);
if (len % 2 == 0)
{
return (med[(len / 2)]
+ med[(len / 2) - 1])
/ 2.0;
}
return med[len / 2];
}
public static void Main(String[] args)
{
int [,]mat = { { 1, 2 }, { 2, 3 } };
int N = mat.GetLength(0);
int M = 2;
Console.WriteLine(findMedXOR(mat, N, M));
}
}
|
Javascript
<script>
function findMedXOR(mat, N, M)
{
let dp = new Array(N);
for (let i = 0; i < N; i++)
dp[i] = new Array(M);
let med = new Array(N * M);
dp[0][0] = mat[0][0];
med[0] = dp[0][0];
let len = 1;
for (let i = 1; i < N; i++) {
dp[i][0]
= dp[i - 1][0] ^ mat[i][0];
med[len++] = dp[i][0];
}
for (let i = 1; i < M; i++) {
dp[0][i]
= dp[0][i - 1] ^ mat[0][i];
med[len++] = dp[0][i];
}
for (let i = 1; i < N; i++) {
for (let j = 1; j < M; j++) {
dp[i][j] = dp[i - 1][j]
^ dp[i][j - 1]
^ dp[i - 1][j - 1]
^ mat[i][j];
med[len++] = dp[i][j];
}
}
med.sort();
if (len % 2 == 0) {
return (med[parseInt(len / 2)]
+ med[parseInt(len / 2) - 1])
/ 2.0;
}
return med[parseInt(len / 2)];
}
let mat = [ [ 1, 2 ], [ 2, 3 ] ];
let N = mat.length;
let M = 2;
document.write(findMedXOR(mat, N, M));
</script>
|
Time Complexity: O(N * M)
Auxiliary Space: O(N * M)
Last Updated :
27 Jul, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...