Suma de AND bit a bit de todos los subarreglos

Dada una array que consta de N enteros positivos, encuentre la suma de bits y de todas las subarreglas posibles de la array.

Ejemplos:  

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 

Solución simple : una solución simple será generar todos los subconjuntos y sumar los valores AND de todos los subconjuntos. En promedio, tomará un tiempo lineal encontrar el valor AND de un subarreglo y, por lo tanto, la complejidad del tiempo total será O(n 3 ).

Solución eficiente: para una mejor comprensión, supongamos que cualquier bit de un elemento está representado por la variable ‘i’, y la variable ‘suma’ se usa para almacenar la suma final.
La idea aquí es que intentaremos encontrar el número de valores AND (sub-arrays con bits y (&)) con i -ésimo conjunto de bits. Supongamos que hay un número ‘S i ‘ de subarrays con i -ésimo conjunto de bits. Para, i -ésimo bit, la suma se puede actualizar como sum += (2 i * S).
Dividiremos la tarea en varios pasos. En cada paso, intentaremos encontrar el número de valores AND con i -ésimo conjunto de bits. Para esto, simplemente iteraremos a través de la array y encontraremos el número de segmentos contiguos con iconjunto de bits y sus longitudes. Para cada segmento de longitud ‘l’, el valor de la suma se puede actualizar como sum += (2 i * l * (l + 1))/2.
Dado que, para cada bit, estamos realizando iteraciones O(N) y como máximo hay bits log(max(A)), la complejidad temporal de este enfoque será O(N*log(max(A)), asumiendo max(A) = valor máximo en la array.

A continuación se muestra la implementación de la idea anterior: 

C++

// CPP program to find sum of bitwise AND
// of all subarrays
 
#include <iostream>
#include <vector>
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

<?php
// PHP program to find sum of bitwise
// AND of all subarrays
 
// Function to find the sum of
// bitwise AND of all subarrays
function findAndSum($arr, $n)
{
    // variable to store the
    // final sum
    $sum = 0;
 
    // multiplier
    $mul = 1;
 
    for ($i = 0; $i < 30; $i++)
    {
         
        // 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 = 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
$arr = array( 7, 1, 1, 5 );
 
$n = sizeof($arr);
 
echo findAndSum($arr, $n);
 
// This code is contributed by Ryuga
?>

Javascript

<script>
 
// Javascript program to find sum of bitwise AND
// of all subarrays
 
// Function to find the sum of
// bitwise AND of all subarrays
function findAndSum(arr, n)
{
    // variable to store
    // the final sum
    var sum = 0;
 
    // multiplier
    var mul = 1;
 
    for (var i = 0; i < 30; i++) {
        // variable to check if
        // counting is on
        var count_on = 0;
 
        // variable to store the
        // length of the subarrays
        var l = 0;
 
        // loop to find the contiguous
        // segments
        for (var 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
var arr = [ 7, 1, 1, 5 ];
var n = arr.length;
document.write( findAndSum(arr, n));
 
</script>
Producción: 

20

 

Complejidad de tiempo : O(N*log(max(A))
Espacio auxiliar: O(1)

Publicación traducida automáticamente

Artículo escrito por DivyanshuShekhar1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *