📌  相关文章
📜  给定数组的所有子数组的按位或运算的总和|套装2

📅  最后修改于: 2021-05-30 16:38:00             🧑  作者: Mango

给出一个正整数数组。任务是在给定数组的所有子数组上执行按位或运算后,找到总和。

例子:

Input : arr[] = {1, 2, 3, 4, 5}
Output : 71

Input : arr[] = {6, 5, 4, 3, 2}
Output : 84

说明

简单方法:一种简单方法是使用两个嵌套循环找到给定数组的每个子数组的按位或,然后找到总和。该方法的时间复杂度将为O(N 2 )。

高效的方法

  1. 在这里观察到,如果数组的某个元素正在设置一个位,那么所有具有该元素的子数组都将设置该位。因此,当我们计算具有该数字的所有子数组的总和时,我们可以将子数组的数量直接乘以该位的值。
  2. 现在,要做到这一点,一个简单的方法就是计算未设置位的子数组的数量,然后从子数组的总数中减去它。

让我们来看一个例子:
令数组A = [1,2,3,4,5] 。现在,第2位和第4位中未设置第1位,按位或将不设置第1位的子数组总数为2。

因此,按位或将具有第一位设置的子阵列总数为:15-2 = 13。

因此,我们将相加(13 * pow(2,0))。

下面是上述方法的实现:

C++
// C++ program to find sum of bitwise OR
// of all subarrays
  
#include 
using namespace std;
  
// Function to find sum of bitwise OR
// of all subarrays
int givesum(int A[], int n)
{
    // Find max element of the array
    int max = *max_element(A, A + n);
  
    // Find the max bit position set in
    // the array
    int maxBit = log2(max) + 1;
  
    int totalSubarrays = n * (n + 1) / 2;
  
    int s = 0;
  
    // Traverse from 1st bit to last bit which
    // can be set in any element of the array
    for (int i = 0; i < maxBit; i++) {
        int c1 = 0;
  
        // Vector to store indexes of the array
        // with i-th bit not set
        vector vec;
  
        int sum = 0;
  
        // Traverse the array
        for (int j = 0; j < n; j++) {
  
            // Check if ith bit is not set in A[j]
            int a = A[j] >> i;
            if (!(a & 1)) {
                vec.push_back(j);
            }
        }
  
        // Variable to store count of subarrays
        // whose bitwise OR will have i-th bit
        // not set
        int cntSubarrNotSet = 0;
  
        int cnt = 1;
  
        for (int j = 1; j < vec.size(); j++) {
            if (vec[j] - vec[j - 1] == 1) {
                cnt++;
            }
            else {
                cntSubarrNotSet += cnt * (cnt + 1) / 2;
  
                cnt = 1;
            }
        }
  
        // For last element of vec
        cntSubarrNotSet += cnt * (cnt + 1) / 2;
  
        // If vec is empty then cntSubarrNotSet
        // should be 0 and not 1
        if (vec.size() == 0)
            cntSubarrNotSet = 0;
  
        // Variable to store count of subarrays
        // whose bitwise OR will have i-th bit set
        int cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
  
        s += cntSubarrIthSet * pow(2, i);
    }
  
    return s;
}
  
// Driver code
int main()
{
    int A[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(A) / sizeof(A[0]);
  
    cout << givesum(A, n);
  
    return 0;
}


Java
// Java program to find sum of bitwise OR
// of all subarrays
import java.util.*;
  
class GFG {
  
    // Function to find sum of bitwise OR
    // of all subarrays
    static int givesum(int A[], int n)
    {
  
        // Find max element of the array
        int max = Arrays.stream(A).max().getAsInt();
  
        // Find the max bit position
        // set in the array
        int maxBit = (int)Math.ceil(Math.log(max) + 1);
        int totalSubarrays = n * (n + 1) / 2;
  
        int s = 0;
  
        // Traverse from 1st bit to last bit which
        // can be set in any element of the array
        for (int i = 0; i < maxBit; i++) {
            int c1 = 0;
  
            // Vector to store indexes of the array
            // with i-th bit not set
            Vector vec = new Vector<>();
  
            int sum = 0;
  
            // Traverse the array
            for (int j = 0; j < n; j++) {
  
                // Check if ith bit is not set in A[j]
                int a = A[j] >> i;
                if (!(a % 2 == 1)) {
                    vec.add(j);
                }
            }
  
            // Variable to store count of subarrays
            // whose bitwise OR will have i-th bit
            // not set
            int cntSubarrNotSet = 0;
  
            int cnt = 1;
  
            for (int j = 1; j < vec.size(); j++) {
                if (vec.get(j) - vec.get(j - 1) == 1) {
                    cnt++;
                }
                else {
                    cntSubarrNotSet += cnt * (cnt + 1) / 2;
  
                    cnt = 1;
                }
            }
  
            // For last element of vec
            cntSubarrNotSet += cnt * (cnt + 1) / 2;
  
            // If vec is empty then cntSubarrNotSet
            // should be 0 and not 1
            if (vec.size() == 0)
                cntSubarrNotSet = 0;
  
            // Variable to store count of subarrays
            // whose bitwise OR will have i-th bit set
            int cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
  
            s += cntSubarrIthSet * Math.pow(2, i);
        }
        return s;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int A[] = { 1, 2, 3, 4, 5 };
        int n = A.length;
        System.out.println(givesum(A, n));
    }
}
  
// This code is contributed by 29AjayKumar


Python3
# Python 3 program to find sum of 
# bitwise OR of all subarrays 
  
# from math lib. import log2 function
from math import log2
  
# Function to find sum of bitwise OR 
# of all subarrays 
def givesum(A, n) :
  
    # Find max element of the array 
    max_element = max(A) 
  
    # Find the max bit position set in 
    # the array 
    maxBit = int(log2(max_element)) + 1
  
    totalSubarrays = n * (n + 1) // 2
  
    s = 0
  
    # Traverse from 1st bit to last bit which 
    # can be set in any element of the array 
    for i in range(maxBit) : 
        c1 = 0
  
        # List to store indexes of the array 
        # with i-th bit not set 
        vec = []
  
        sum = 0
  
        # Traverse the array 
        for j in range(n) : 
  
            # Check if ith bit is not set in A[j] 
            a = A[j] >> i
              
            if (not(a & 1)) :
                vec.append(j)
  
        # Variable to store count of subarrays 
        # whose bitwise OR will have i-th bit 
        # not set 
        cntSubarrNotSet = 0
  
        cnt = 1
  
        for j in range(1, len(vec)) :
              
            if (vec[j] - vec[j - 1] == 1) : 
                cnt += 1
              
            else :
                  
                cntSubarrNotSet += cnt * (cnt + 1) // 2
  
                cnt = 1
              
        # For last element of vec 
        cntSubarrNotSet += cnt * (cnt + 1) // 2
  
        # If vec is empty then cntSubarrNotSet 
        # should be 0 and not 1
        if len(vec) == 0:
            cntSubarrNotSet = 0    
  
        # Variable to store count of subarrays 
        # whose bitwise OR will have i-th bit set 
        cntSubarrIthSet = totalSubarrays - cntSubarrNotSet 
  
        s += cntSubarrIthSet * pow(2, i) 
      
    return s
  
# Driver code 
if __name__ == "__main__" :
  
    A = [ 1, 2, 3, 4, 5 ]
    n = len(A)
  
    print(givesum(A, n))
  
# This code is contributed by Ryuga


C#
// C# program to find sum of bitwise OR
// of all subarrays
using System;
using System.Linq;
using System.Collections.Generic;
  
class GFG {
  
    // Function to find sum of bitwise OR
    // of all subarrays
    static int givesum(int[] A, int n)
    {
  
        // Find max element of the array
        int max = A.Max();
  
        // Find the max bit position
        // set in the array
        int maxBit = (int)Math.Ceiling(Math.Log(max) + 1);
        int totalSubarrays = n * (n + 1) / 2;
  
        int s = 0;
  
        // Traverse from 1st bit to last bit which
        // can be set in any element of the array
        for (int i = 0; i < maxBit; i++) {
  
            // Vector to store indexes of the array
            // with i-th bit not set
            List vec = new List();
  
            // Traverse the array
            for (int j = 0; j < n; j++) {
  
                // Check if ith bit is not set in A[j]
                int a = A[j] >> i;
                if (!(a % 2 == 1)) {
                    vec.Add(j);
                }
            }
  
            // Variable to store count of subarrays
            // whose bitwise OR will have i-th bit
            // not set
            int cntSubarrNotSet = 0;
  
            int cnt = 1;
  
            for (int j = 1; j < vec.Count; j++) {
                if (vec[j] - vec[j - 1] == 1) {
                    cnt++;
                }
                else {
                    cntSubarrNotSet += cnt * (cnt + 1) / 2;
  
                    cnt = 1;
                }
            }
  
            // For last element of vec
            cntSubarrNotSet += cnt * (cnt + 1) / 2;
  
            // If vec is empty then cntSubarrNotSet
            // should be 0 and not 1
            if (vec.Count() == 0)
                cntSubarrNotSet = 0;
  
            // Variable to store count of subarrays
            // whose bitwise OR will have i-th bit set
            int cntSubarrIthSet = totalSubarrays - cntSubarrNotSet;
  
            s += (int)(cntSubarrIthSet * Math.Pow(2, i));
        }
        return s;
    }
  
    // Driver code
    public static void Main()
    {
        int[] A = { 1, 2, 3, 4, 5 };
        int n = A.Length;
        Console.WriteLine(givesum(A, n));
    }
}
  
/* This code contributed by PrinciRaj1992 */


PHP
> $i;
            if (!($a & 1))
            {
                array_push($vec, $j);
            }
        }
  
        // Variable to store count of subarrays
        // whose bitwise OR will have i-th bit
        // not set
        $cntSubarrNotSet = 0;
  
        $cnt = 1;
  
        for ($j = 1; $j < count($vec); $j++) 
        {
            if ($vec[$j] - $vec[$j - 1] == 1)
            {
                $cnt++;
            }
            else 
            {
                $cntSubarrNotSet += (int)($cnt * 
                                         ($cnt + 1) / 2);
  
                $cnt = 1;
            }
        }
  
        // For last element of vec
        $cntSubarrNotSet += (int)($cnt *
                                 ($cnt + 1) / 2);
  
        // If vec is empty then cntSubarrNotSet 
        // should be 0 and not 1
        if (count($vec) == 0)
            $cntSubarrNotSet = 0;
  
        // Variable to store count of subarrays
        // whose bitwise OR will have i-th bit set
        $cntSubarrIthSet = $totalSubarrays - 
                           $cntSubarrNotSet;
  
        $s += $cntSubarrIthSet * pow(2, $i);
    }
  
    return $s;
}
  
// Driver code
$A = array( 1, 2, 3, 4, 5 );
$n = count($A);
  
echo givesum($A, $n);
  
// This code is contributed by mits
?>


输出:
71

时间复杂度:O(N * logN)

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。