给定一个由N个正整数组成的数组,请找到按位与该数组所有可能的子数组的总和。
例子:
Input : arr[] = {1, 5, 8}
Output : 15
Bit-wise AND of {1} = 1
Bit-wise AND of {1, 5} = 1
Bit-wise AND of {1, 5, 8} = 0
Bit-wise AND of {5} = 5
Bit-wise AND of {5, 8} = 0
Bit-wise AND of {8} = 8
Sum = 1 + 1 + 0 + 5 + 0 + 8 = 15
Input : arr[] = {7, 1, 1, 5}
Output : 20
简单解决方案:一个简单的解决方案是生成所有子数组,并对所有子数组的AND值求和。平均来说,找到子数组的AND值将花费线性时间,因此,总的时间复杂度将为O(n 3 )。
高效的解决方案:为了更好地理解,我们假定元素的任何位都由变量’i’表示,并且变量’sum’用于存储最终和。
这里的想法是,我们将尝试找到第i个位设置为AND的数量(按位与(&)的子数组)。让我们假设,存在第i个位设置为’S i ‘的子阵列。对于,第i位,总和可以更新为总和+ =(2 i * S)。
我们会将任务分为多个步骤。在每一步中,我们将尝试找到第i个位设置为AND的数量。为此,我们将简单地遍历数组并找到设置有第i个位并具有长度的连续段的数量。对于每个这样的长度为“ l”的段,sum的值可以更新为sum + =(2 i * l *(l + 1))/ 2。
由于对于每个位,我们正在执行O(N)次迭代,并且由于最多有log(max(A))个位,因此,假设该方法的时间复杂度为O(N * log(max(A)) max(A)=数组中的最大值。
下面是上述想法的实现:
C++
// CPP program to find sum of bitwise AND
// of all subarrays
#include
#include
using namespace std;
// Function to find the sum of
// bitwise AND of all subarrays
int findAndSum(int arr[], int n)
{
// variable to store
// the final sum
int sum = 0;
// multiplier
int mul = 1;
for (int i = 0; i < 30; i++) {
// variable to check if
// counting is on
bool count_on = 0;
// variable to store the
// length of the subarrays
int l = 0;
// loop to find the contiguous
// segments
for (int j = 0; j < n; j++) {
if ((arr[j] & (1 << i)) > 0)
if (count_on)
l++;
else {
count_on = 1;
l++;
}
else if (count_on) {
sum += ((mul * l * (l + 1)) / 2);
count_on = 0;
l = 0;
}
}
if (count_on) {
sum += ((mul * l * (l + 1)) / 2);
count_on = 0;
l = 0;
}
// updating the multiplier
mul *= 2;
}
// returning the sum
return sum;
}
// Driver Code
int main()
{
int arr[] = { 7, 1, 1, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << findAndSum(arr, n);
return 0;
}
Java
// Java program to find sum of bitwise AND
// of all subarrays
class GFG
{
// Function to find the sum of
// bitwise AND of all subarrays
static int findAndSum(int []arr, int n)
{
// variable to store
// the final sum
int sum = 0;
// multiplier
int mul = 1;
for (int i = 0; i < 30; i++)
{
// variable to check if
// counting is on
boolean count_on = false;
// variable to store the
// length of the subarrays
int l = 0;
// loop to find the contiguous
// segments
for (int j = 0; j < n; j++)
{
if ((arr[j] & (1 << i)) > 0)
if (count_on)
l++;
else
{
count_on = true;
l++;
}
else if (count_on)
{
sum += ((mul * l * (l + 1)) / 2);
count_on = false;
l = 0;
}
}
if (count_on)
{
sum += ((mul * l * (l + 1)) / 2);
count_on = false;
l = 0;
}
// updating the multiplier
mul *= 2;
}
// returning the sum
return sum;
}
// Driver Code
public static void main(String[] args)
{
int []arr = { 7, 1, 1, 5 };
int n = arr.length;
System.out.println(findAndSum(arr, n));
}
}
// This code is contributed
// by Code_Mech.
Python3
# Python3 program to find Sum of
# bitwise AND of all subarrays
import math as mt
# Function to find the Sum of
# bitwise AND of all subarrays
def findAndSum(arr, n):
# variable to store the final Sum
Sum = 0
# multiplier
mul = 1
for i in range(30):
# variable to check if counting is on
count_on = 0
# variable to store the length
# of the subarrays
l = 0
# loop to find the contiguous
# segments
for j in range(n):
if ((arr[j] & (1 << i)) > 0):
if (count_on):
l += 1
else:
count_on = 1
l += 1
elif (count_on):
Sum += ((mul * l * (l + 1)) // 2)
count_on = 0
l = 0
if (count_on):
Sum += ((mul * l * (l + 1)) // 2)
count_on = 0
l = 0
# updating the multiplier
mul *= 2
# returning the Sum
return Sum
# Driver Code
arr = [7, 1, 1, 5]
n = len(arr)
print(findAndSum(arr, n))
# This code is contributed by Mohit Kumar
C#
// C# program to find sum of bitwise AND
// of all subarrays
using System;
class GFG
{
// Function to find the sum of
// bitwise AND of all subarrays
static int findAndSum(int []arr, int n)
{
// variable to store
// the final sum
int sum = 0;
// multiplier
int mul = 1;
for (int i = 0; i < 30; i++)
{
// variable to check if
// counting is on
bool count_on = false;
// variable to store the
// length of the subarrays
int l = 0;
// loop to find the contiguous
// segments
for (int j = 0; j < n; j++)
{
if ((arr[j] & (1 << i)) > 0)
if (count_on)
l++;
else
{
count_on = true;
l++;
}
else if (count_on)
{
sum += ((mul * l * (l + 1)) / 2);
count_on = false;
l = 0;
}
}
if (count_on)
{
sum += ((mul * l * (l + 1)) / 2);
count_on = false;
l = 0;
}
// updating the multiplier
mul *= 2;
}
// returning the sum
return sum;
}
// Driver Code
public static void Main()
{
int []arr = { 7, 1, 1, 5 };
int n = arr.Length;
Console.Write(findAndSum(arr, n));
}
}
// This code is contributed
// by Akanksha Rai
PHP
0)
if ($count_on)
$l++;
else
{
$count_on = 1;
$l++;
}
else if ($count_on)
{
$sum += (($mul * $l * ($l + 1)) / 2);
$count_on = 0;
$l = 0;
}
}
if ($count_on)
{
$sum += (($mul * $l * ($l + 1)) / 2);
$count_on = 0;
$l = 0;
}
// updating the multiplier
$mul *= 2;
}
// returning the sum
return $sum;
}
// Driver Code
$arr = array( 7, 1, 1, 5 );
$n = sizeof($arr);
echo findAndSum($arr, $n);
// This code is contributed by Ryuga
?>
输出:
20
时间复杂度:O(N * log(max(A))