给定一个NxN矩阵,任务是找到所有矩形子矩阵的按位或的总和。
例子:
Input : arr[][] = {{1, 0, 0},
{0, 0, 0},
{0, 0, 0}}
Output : 9
Explanation: All the submatrices starting from
the index (0, 0) will have OR value as 1.
Thus, ans = 9
Input : arr[][] = {{9, 7, 4},
{8, 9, 2},
{11, 11, 5}}
Output : 398
先决条件:OR值为1的子矩阵的数量
简单解决方案:一个简单的解决方案是生成所有子矩阵,并为每个子矩阵找到所需的OR值。该方法的时间复杂度将为O(N 6 )。
高效的解决方案:为了更好地理解,我们假定元素的任何位都由变量’i’表示,并且变量’sum’用于存储最终和。
这里的想法是,我们将尝试找到设置有第i个位的OR值(按位或(|)的子矩阵)的数量。让我们假设,有第i个位设置的S i个子矩阵。对于,第i位,总和可以更新为总和+ =(2 i * S i )。
对于每个位“ i”,如果设置了arr [R] [C]的第i个位,则创建一个布尔矩阵set_bit ,将其存储在索引(R,C)处为“ 1”。否则,它存储为“ 0”。然后,对于此布尔数组,我们尝试找到OR值为1(S i )的矩形子矩阵的数量。因为,第i位,最后一笔将被更新为:
sum += 2i * Si
下面是上述方法的实现:
C++
// C++ program to find sum of Bitwise-OR of
// all submatrices
#include
#include
using namespace std;
#define n 3
// Function to find prefix-count for each row
// from right to left
void findPrefixCount(int p_arr[][n], bool set_bit[][n])
{
for (int i = 0; i < n; i++)
{
for (int j = n - 1; j >= 0; j--)
{
if (set_bit[i][j])
continue;
if (j != n - 1)
p_arr[i][j] += p_arr[i][j + 1];
p_arr[i][j] += (int)(!set_bit[i][j]);
}
}
}
// Function to create a boolean matrix set_bit which
// stores ‘1’ at an index (R, C) if ith bit
// of arr[R][C] is set.
int matrixOrValueOne(bool set_bit[][n])
{
// array to store prefix count of zeros from
// right to left for boolean array
int p_arr[n][n] = { 0 };
findPrefixCount(p_arr, set_bit);
// variable to store the count of
// submatrices with OR value 0
int count_zero_submatrices = 0;
// For each index of a column we will try to
// determine the number of sub-matrices
// starting from that index
// and has all 1s
for (int j = 0; j < n; j++)
{
int i = n - 1;
// stack to store elements and the count
// of the numbers they popped
// First part of pair will be the
// value of inserted element.
// Second part will be the count
// of the number of elements pushed
// before with a greater value
stack > q;
// variable to store the number of submatrices
// with all 0s
int to_sum = 0;
while (i >= 0)
{
int c = 0;
while (q.size() != 0 and q.top().first > p_arr[i][j])
{
to_sum -= (q.top().second + 1) *
(q.top().first - p_arr[i][j]);
c += q.top().second + 1;
q.pop();
}
to_sum += p_arr[i][j];
count_zero_submatrices += to_sum;
q.push({ p_arr[i][j], c });
i--;
}
}
return (n * (n + 1) * n * (n + 1)) /
4 - count_zero_submatrices;
}
// Function to find sum of Bitwise-OR of
// all submatrices
int sumOrMatrix(int arr[][n])
{
int sum = 0;
int mul = 1;
for (int i = 0; i < 30; i++)
{
// matrix to store the status
// of ith bit of each element
// of matrix arr
bool set_bit[n][n];
for (int R = 0; R < n; R++)
for (int C = 0; C < n; C++)
set_bit[R][C] = ((arr[R][C] & (1 << i)) != 0);
sum += (mul * matrixOrValueOne(set_bit));
mul *= 2;
}
return sum;
}
// Driver Code
int main()
{
int arr[][n] = { { 9, 7, 4 },
{ 8, 9, 2 },
{ 11, 11, 5 } };
cout << sumOrMatrix(arr);
return 0;
}
Java
// Java program to find sum of Bitwise-OR of
// all submatrices
import java.util.*;
class GFG
{
static int n = 3;
// Function to find prefix-count for
// each row from right to left
static void findPrefixCount(int p_arr[][],
boolean set_bit[][])
{
for (int i = 0; i < n; i++)
{
for (int j = n - 1; j >= 0; j--)
{
if (set_bit[i][j])
continue;
if (j != n - 1)
p_arr[i][j] += p_arr[i][j + 1];
p_arr[i][j] += (!set_bit[i][j]) ? 1 : 0;
}
}
}
static class pair
{
int first,second;
pair(){}
pair(int a,int b)
{
first = a;
second = b;
}
}
// Function to create a booleanean
// matrix set_bit which stores '1'
// at an index (R, C) if ith bit
// of arr[R][C] is set.
static int matrixOrValueOne(boolean set_bit[][])
{
// array to store prefix count of zeros from
// right to left for booleanean array
int p_arr[][] = new int[n][n] ;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
p_arr[i][j] = 0;
findPrefixCount(p_arr, set_bit);
// variable to store the count of
// submatrices with OR value 0
int count_zero_submatrices = 0;
// For each index of a column we will try to
// determine the number of sub-matrices
// starting from that index
// and has all 1s
for (int j = 0; j < n; j++)
{
int i = n - 1;
// stack to store elements and the count
// of the numbers they popped
// First part of pair will be the
// value of inserted element.
// Second part will be the count
// of the number of elements pushed
// before with a greater value
Stack q = new Stack();
// variable to store the number of submatrices
// with all 0s
int to_sum = 0;
while (i >= 0)
{
int c = 0;
while (q.size() != 0 && q.peek().first > p_arr[i][j])
{
to_sum -= (q.peek().second + 1) *
(q.peek().first - p_arr[i][j]);
c += q.peek().second + 1;
q.pop();
}
to_sum += p_arr[i][j];
count_zero_submatrices += to_sum;
q.push(new pair( p_arr[i][j], c ));
i--;
}
}
return (n * (n + 1) * n * (n + 1)) /
4 - count_zero_submatrices;
}
// Function to find sum of Bitwise-OR of
// all submatrices
static int sumOrMatrix(int arr[][])
{
int sum = 0;
int mul = 1;
for (int i = 0; i < 30; i++)
{
// matrix to store the status
// of ith bit of each element
// of matrix arr
boolean set_bit[][] = new boolean[n][n];
for (int R = 0; R < n; R++)
for (int C = 0; C < n; C++)
set_bit[R][C] = ((arr[R][C] & (1 << i)) != 0);
sum += (mul * matrixOrValueOne(set_bit));
mul *= 2;
}
return sum;
}
// Driver Code
public static void main(String args[])
{
int arr[][] = { { 9, 7, 4 },
{ 8, 9, 2 },
{ 11, 11, 5 } };
System.out.println( sumOrMatrix(arr));
}
}
// This code is contributed by Arnab Kundu
Python3
# Python3 program to find sum of
# Bitwise-OR of all submatrices
# Function to find prefix-count for
# each row from right to left
def findPrefixCount(p_arr, set_bit):
for i in range(0, n):
for j in range(n - 1, -1, -1):
if set_bit[i][j]:
continue
if j != n - 1:
p_arr[i][j] += p_arr[i][j + 1]
p_arr[i][j] += int(not set_bit[i][j])
# Function to create a boolean matrix
# set_bit which stores ‘1’ at an index
# (R, C) if ith bit of arr[R][C] is set.
def matrixOrValueOne(arr):
# Array to store prefix count of zeros
# from right to left for boolean array
p_arr = [[0 for i in range(n)]
for j in range(n)]
findPrefixCount(p_arr, arr)
# Variable to store the count of
# submatrices with OR value 0
count_zero_submatrices = 0
# Loop to evaluate each column of
# the prefix matrix uniquely.
# For each index of a column we will try
# to determine the number of sub-matrices
# starting from that index and has all 1s
for j in range(0, n):
i = n - 1
# stack to store elements and the
# count of the numbers they popped
# First part of pair will be the
# value of inserted element.
# Second part will be the count
# of the number of elements pushed
# before with a greater value
q = []
# Variable to store the number
# of submatrices with all 0s
to_sum = 0
while i >= 0:
c = 0
while (len(q) != 0 and
q[-1][0] > p_arr[i][j]):
to_sum -= ((q[-1][1] + 1) *
(q[-1][0] - p_arr[i][j]))
c += q.pop()[1] + 1
to_sum += p_arr[i][j]
count_zero_submatrices += to_sum
q.append((p_arr[i][j], c))
i -= 1
# Return the final answer
return ((n * (n + 1) * n * (n + 1)) //
4 - count_zero_submatrices)
# Function to find sum of
# Bitwise-OR of all submatrices
def sumOrMatrix(arr):
Sum, mul = 0, 1
for i in range(0, 30):
# matrix to store the status
# of ith bit of each element
# of matrix arr
set_bit = [[False for i in range(n)]
for j in range(n)]
for R in range(0, n):
for C in range(0, n):
set_bit[R][C] = ((arr[R][C] &
(1 << i)) != 0)
Sum += (mul * matrixOrValueOne(set_bit))
mul *= 2
return Sum
# Driver Code
if __name__ == "__main__":
n = 3
arr = [[9, 7, 4],
[8, 9, 2],
[11, 11, 5]]
print(sumOrMatrix(arr))
# This code is contributed by Rituraj Jain
C#
// C# program to find sum of Bitwise-OR of
// all submatrices
using System;
using System.Collections.Generic;
class GFG
{
static int n = 3;
// Function to find prefix-count for
// each row from right to left
static void findPrefixCount(int [,]p_arr,
Boolean [,]set_bit)
{
for (int i = 0; i < n; i++)
{
for (int j = n - 1; j >= 0; j--)
{
if (set_bit[i, j])
continue;
if (j != n - 1)
p_arr[i, j] += p_arr[i, j + 1];
p_arr[i, j] += (!set_bit[i, j]) ? 1 : 0;
}
}
}
public class pair
{
public int first,second;
public pair(){}
public pair(int a, int b)
{
first = a;
second = b;
}
}
// Function to create a booleanean
// matrix set_bit which stores '1'
// at an index (R, C) if ith bit
// of arr[R,C] is set.
static int matrixOrValueOne(Boolean [,]set_bit)
{
// array to store prefix count of zeros from
// right to left for booleanean array
int [,]p_arr = new int[n, n];
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
p_arr[i, j] = 0;
findPrefixCount(p_arr, set_bit);
// variable to store the count of
// submatrices with OR value 0
int count_zero_submatrices = 0;
// For each index of a column we will try to
// determine the number of sub-matrices
// starting from that index
// and has all 1s
for (int j = 0; j < n; j++)
{
int i = n - 1;
// stack to store elements and the count
// of the numbers they popped
// First part of pair will be the
// value of inserted element.
// Second part will be the count
// of the number of elements pushed
// before with a greater value
Stack q = new Stack();
// variable to store the number of
// submatrices with all 0s
int to_sum = 0;
while (i >= 0)
{
int c = 0;
while (q.Count != 0 &&
q.Peek().first > p_arr[i, j])
{
to_sum -= (q.Peek().second + 1) *
(q.Peek().first - p_arr[i, j]);
c += q.Peek().second + 1;
q.Pop();
}
to_sum += p_arr[i, j];
count_zero_submatrices += to_sum;
q.Push(new pair(p_arr[i, j], c));
i--;
}
}
return (n * (n + 1) * n * (n + 1)) /
4 - count_zero_submatrices;
}
// Function to find sum of Bitwise-OR of
// all submatrices
static int sumOrMatrix(int [,]arr)
{
int sum = 0;
int mul = 1;
for (int i = 0; i < 30; i++)
{
// matrix to store the status
// of ith bit of each element
// of matrix arr
Boolean [,]set_bit = new Boolean[n, n];
for (int R = 0; R < n; R++)
for (int C = 0; C < n; C++)
set_bit[R, C] = ((arr[R, C] &
(1 << i)) != 0);
sum += (mul * matrixOrValueOne(set_bit));
mul *= 2;
}
return sum;
}
// Driver Code
public static void Main(String []args)
{
int [,]arr = {{ 9, 7, 4 },
{ 8, 9, 2 },
{ 11, 11, 5 }};
Console.WriteLine( sumOrMatrix(arr));
}
}
// This code is contributed by Rajput-Ji
输出:
398
时间复杂度:O(N 2 )。