Suma de AND bit a bit de suma de pares y su AND bit a bit de una array dada

Dada una array arr[] que consta de N enteros, la tarea es encontrar la suma de Bitwise AND de (arr[i] + arr[j]) y Bitwise AND de arr[i] y arr[j] para cada par de elementos (arr[i], arr[j]) de la array dada. Como la suma puede ser muy grande, imprímela módulo (10 9 + 7) .

Ejemplos:

Entrada: arr[] = {8, 9}
Salida: 0
Explicación: El único par de la array es (8, 9). Suma del par = (8 + 9) = 17. Y bit a bit de los pares = (8 y 9) = 8. Por lo tanto, se requiere AND bit a bit = (17 y 8) = 0.

Entrada: arr[] = {1, 3, 3}
Salida: 2
Explicación:
Par (1, 3): Obligatorio Bit a bit AND = (1 + 3) & (1 & 3) = (4 & 1) = 0.
Par (3, 3): Obligatorio Bitwise AND = (3 + 3) & (3 & 3) = (6 & 3) = 2.
Por lo tanto, la suma total = 0 + 0 + 2 = 2.

Enfoque ingenuo: el enfoque más simple es generar todos los pares posibles a partir de la array dada y verificar si existe algún par que satisfaga la condición dada o no. Si se encuentra que es cierto, entonces cuente este par. Después de verificar todos los pares, imprima el conteo resultante . 
Complejidad de Tiempo: O(N 2 )
Espacio Auxiliar: O(1)

Enfoque eficiente: el enfoque anterior se puede optimizar en función de las siguientes observaciones:

  • Teniendo en cuenta el par (X, Y) , el AND a nivel de bits en un bit, digamos que b th es 1 , entonces (X + Y) también debe tener el b th bit como un bit establecido para contribuir en el b th bit.
  • Considerando sólo los últimos b bits de ambos números de dichos pares, se puede observar que para satisfacer la condición anterior, b -ésimo bit y (b + 1) -ésimo bit, ambos deberán establecerse.
  • Por lo tanto, de los pasos anteriores, se puede deducir que para satisfacer las condiciones anteriores, se debe cumplir la siguiente condición:

X + Y - 2^{b+1} - 2^{b} >= 0 \newline Y >= 3 * 2^{b} - X

  • Por lo tanto, la tarea se reduce a encontrar el conteo de pares que satisfacen la condición anterior para cada posición de bit e incrementar el resultado por el valor cnt*2 b  para 0 ≤ b < 31 .

Siga los pasos a continuación para resolver el problema:

  • Inicialice una variable, digamos ans , para almacenar la suma resultante.
  • Itere sobre el rango [0, 30] y realice las siguientes operaciones:
    • Inicialice un vector V que almacene los pares que cumplan las condiciones anteriores.
    • Recorra la array dada arr[] e inserte el valor arr[j] – (arr[j] >> (i + 1))*(1 << (i + 1)) módulo M en el vector V , si (( arr[j] >> (i + 1)) &1) es verdadero.
    • Ordena el vector V en orden ascendente .
    • Recorra el vector V y realice lo siguiente:
      • Calcule el valor 2 (i + 1) + 2 i – V[j] y guárdelo en una variable, digamos Y .
      • Encuentra el número de puntos en V que es mayor o igual que Y en V y guárdalo en una variable, digamos cnt , es decir, cnt = V.size() – (lower_bound(V.begin() + j + 1, V.end(), Y) – V.begin()).
      • Actualice el ans como ans = (ans+ cnt* 2 i )%M .
  • Después de completar los pasos anteriores, imprima el valor de ans como resultado.

A continuación se muestra la implementación del enfoque anterior:

C++14

// C++ program for the above approach
 
#include <bits/stdc++.h>
#define M 1000000007
using namespace std;
 
// Function to find the sum of Bitwise AND
// of sum of pairs and their Bitwise AND
// from a given array
void findSum(int A[], int N)
{
    // Stores the total sum
    long long ans = 0;
 
    for (int i = 0; i < 30; i++) {
 
        vector<long long> vec;
 
        for (int j = 0; j < N; j++) {
 
            // Check if jth bit is set
            if ((A[j] >> i) & 1) {
 
                // Stores the right shifted
                // element by(i+1)
                long long X = (A[j] >> (i + 1));
 
                // Update the value
                // of X
                X = X * (1 << (i + 1));
                X %= M;
 
                // Push in vector vec
                vec.push_back(A[j] - X);
            }
        }
        // Sort the vector in
        // ascending order
        sort(vec.begin(), vec.end());
 
        // Traverse the vector vec
        for (int j = 0; j < vec.size(); j++) {
 
            // Stores the value
            // 2^(i+1)- 2^(i)- vec[j]
            int Y = (1 << (i + 1))
                    + (1 << i)
                    - vec[j];
 
            // Stores count of numbers
            // whose value > Y
            int idx = lower_bound(
                          vec.begin() + j + 1,
                          vec.end(), Y)
                      - vec.begin();
 
            // Update the ans
            ans += (vec.size() - idx)
                   * 1ll * (1 << i);
 
            ans %= M;
        }
    }
 
    // Return the ans
    cout << ans % M << endl;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 3, 3 };
    int N = sizeof(arr) / sizeof(arr[0]);
    findSum(arr, N);
 
    return 0;
}

Python3

# Python 3 program for the above approach
M = 1000000007
from bisect import bisect_left
 
# Function to find the sum of Bitwise AND
# of sum of pairs and their Bitwise AND
# from a given array
def findSum(A, N):
   
    # Stores the total sum
    ans = 0
 
    for i in range(30):
        vec = []
 
        for j in range(N):
            # Check if jth bit is set
            if ((A[j] >> i) & 1):
                # Stores the right shifted
                # element by(i+1)
                X = (A[j] >> (i + 1))
 
                # Update the value
                # of X
                X = X * (1 << (i + 1))
                X %= M
 
                # Push in vector vec
                vec.append(A[j] - X)
 
        # Sort the vector in
        # ascending order
        vec.sort(reverse=False)
 
        # Traverse the vector vec
        for j in range(len(vec)):
           
            # Stores the value
            # 2^(i+1)- 2^(i)- vec[j]
            Y = (1 << (i + 1)) + (1 << i) - vec[j]
 
            # Stores count of numbers
            # whose value > Y
            temp = vec[j+1:]
            idx = int(bisect_left(temp,Y))
 
            # Update the ans
            ans += ((len(vec) - idx) * (1 << i))
 
            ans %= M
    ans /= 7
 
    # Return the ans
    print(int(ans % M))
 
# Driver Code
if __name__ == '__main__':
    arr =  [1, 3, 3]
    N = len(arr)
    findSum(arr, N)
 
    # This code is contributed by SURENNDRA_GANGWAR.
Producción: 

2

 

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

Publicación traducida automáticamente

Artículo escrito por koulick_sadhu 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 *