📌  相关文章
📜  数组中具有相同AND,OR和XOR值的子集数

📅  最后修改于: 2021-06-25 17:15:38             🧑  作者: Mango

给定大小为N的数组arr [] ,该数组arr []由非负整数组成,任务是找到该数组的非空子集的数量,以使子序列的按位与,按位或和按位XOR值等于每个其他。

注意:由于答案可能很大,请使用1000000007对其进行修改

例子:

朴素的方法针对此问题的朴素的方法是以迭代的方式遍历数组的所有子集,并为每个子集找到按位AND,OR和XOR值,并检查它们是否相等。最后,返回此类相等子集的计数。

下面是上述方法的实现:

C++
// C++ implementation to find the number
// of subsets with equal bitwise AND,
// OR and XOR values
 
#include 
using namespace std;
const int mod = 1000000007;
 
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
int countSubsets(int a[], int n)
{
    int answer = 0;
 
    // Traverse through all the subsets
    for (int i = 0; i < (1 << n); i++) {
 
        int bitwiseAND = -1;
        int bitwiseOR = 0;
        int bitwiseXOR = 0;
 
        // Finding the subsets with the bits
        // of 'i' which are set
        for (int j = 0; j < n; j++) {
 
            // Computing the bitwise AND
            if (i & (1 << j)) {
                if (bitwiseAND == -1)
                    bitwiseAND = a[j];
                else
                    bitwiseAND &= a[j];
 
                // Computing the bitwise OR
                bitwiseOR |= a[j];
 
                // Computing the bitwise XOR
                bitwiseXOR ^= a[j];
            }
        }
 
        // Comparing all the three values
        if (bitwiseAND == bitwiseOR
            && bitwiseOR == bitwiseXOR)
            answer = (answer + 1) % mod;
    }
    return answer;
}
 
// Driver code
int main()
{
    int N = 6;
    int A[N] = { 1, 3, 2, 1, 2, 1 };
 
    cout << countSubsets(A, N);
 
    return 0;
}


Java
// Java implementation to find the number
// of subsets with equal bitwise AND,
// OR and XOR values
import java.io.*;
 
class GFG {
static int mod = 1000000007;
 
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
static int countSubsets(int a[], int n)
{
    int answer = 0;
 
    // Traverse through all the subsets
    for (int i = 0; i < (1 << n); i++) {
 
        int bitwiseAND = -1;
        int bitwiseOR = 0;
        int bitwiseXOR = 0;
 
        // Finding the subsets with the bits
        // of 'i' which are set
        for (int j = 0; j < n; j++) {
 
            // Computing the bitwise AND
            if ((i & (1 << j)) == 0) {
                if (bitwiseAND == -1)
                    bitwiseAND = a[j];
                else
                    bitwiseAND &= a[j];
 
                // Computing the bitwise OR
                bitwiseOR |= a[j];
 
                // Computing the bitwise XOR
                bitwiseXOR ^= a[j];
            }
        }
 
        // Comparing all the three values
        if (bitwiseAND == bitwiseOR
            && bitwiseOR == bitwiseXOR)
            answer = (answer + 1) % mod;
    }
    return answer;
}
 
// Driver Code
public static void main (String[] args)
{
    int N = 6;
    int A[] = { 1, 3, 2, 1, 2, 1 };
 
    System.out.print(countSubsets(A, N));
}
}
 
// This code is contributed by shivanisinghss2110


Python3
# Python3 implementation to find the number
# of subsets with equal bitwise AND,
# OR and XOR values
 
mod = 1000000007;
 
# Function to find the number of
# subsets with equal bitwise AND,
# OR and XOR values
def countSubsets(a, n) :
 
    answer = 0;
 
    # Traverse through all the subsets
    for i in range(1 << n) :
 
        bitwiseAND = -1;
        bitwiseOR = 0;
        bitwiseXOR = 0;
 
        # Finding the subsets with the bits
        # of 'i' which are set
        for j in range(n) :
 
            # Computing the bitwise AND
            if (i & (1 << j)) :
                if (bitwiseAND == -1) :
                    bitwiseAND = a[j];
                else :
                    bitwiseAND &= a[j];
 
                # Computing the bitwise OR
                bitwiseOR |= a[j];
 
                # Computing the bitwise XOR
                bitwiseXOR ^= a[j];
 
        # Comparing all the three values
        if (bitwiseAND == bitwiseOR and bitwiseOR == bitwiseXOR) :
            answer = (answer + 1) % mod;
     
    return answer;
 
# Driver code
if __name__ == "__main__" :
     
    N = 6;
    A = [ 1, 3, 2, 1, 2, 1 ];
 
    print(countSubsets(A, N));
 
# This code is contributed by AnkitRai01


C#
// C# implementation to find the number
// of subsets with equal bitwise AND,
// OR and XOR values
using System;
 
class GFG {
static int mod = 1000000007;
  
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
static int countSubsets(int []a, int n)
{
    int answer = 0;
  
    // Traverse through all the subsets
    for (int i = 0; i < (1 << n); i++) {
  
        int bitwiseAND = -1;
        int bitwiseOR = 0;
        int bitwiseXOR = 0;
  
        // Finding the subsets with the bits
        // of 'i' which are set
        for (int j = 0; j < n; j++) {
  
            // Computing the bitwise AND
            if ((i & (1 << j)) == 0) {
                if (bitwiseAND == -1)
                    bitwiseAND = a[j];
                else
                    bitwiseAND &= a[j];
  
                // Computing the bitwise OR
                bitwiseOR |= a[j];
  
                // Computing the bitwise XOR
                bitwiseXOR ^= a[j];
            }
        }
  
        // Comparing all the three values
        if (bitwiseAND == bitwiseOR
            && bitwiseOR == bitwiseXOR)
            answer = (answer + 1) % mod;
    }
    return answer;
}
  
// Driver Code
public static void Main(String[] args)
{
    int N = 6;
    int []A = { 1, 3, 2, 1, 2, 1 };
  
    Console.Write(countSubsets(A, N));
}
}
 
// This code is contributed by 29AjayKumar


Javascript


C++
// C++ program to find the number
// of subsets with equal bitwise
// AND, OR and XOR values
 
#include 
using namespace std;
const int mod = 1000000007;
 
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
int countSubsets(int a[], int n)
{
    int answer = 0;
 
    // Precompute the modded powers
    // of two for subset counting
    int powerOfTwo[100005];
    powerOfTwo[0] = 1;
 
    // Loop to iterate and find the modded
    // powers of two for subset counting
    for (int i = 1; i < 100005; i++)
        powerOfTwo[i]
            = (powerOfTwo[i - 1] * 2)
              % mod;
 
    // Map to store the frequency of
    // each element
    unordered_map frequency;
 
    // Loop to compute the frequency
    for (int i = 0; i < n; i++)
        frequency[a[i]]++;
 
    // For every element > 0, the number of
    // subsets formed using this element only
    // is equal to 2 ^ (frequency[element]-1).
    // And for 0, we have to find all
    // the subsets, so 2^(frequency[element]) -1
    for (auto el : frequency) {
 
        // If element is greater than 0
        if (el.first != 0)
            answer
                = (answer % mod
                   + powerOfTwo[el.second - 1])
                  % mod;
 
        else
            answer
                = (answer % mod
                   + powerOfTwo[el.second]
                   - 1 + mod)
                  % mod;
    }
    return answer;
}
 
// Driver code
int main()
{
    int N = 6;
    int A[N] = { 1, 3, 2, 1, 2, 1 };
 
    cout << countSubsets(A, N);
 
    return 0;
}


Java
// Java program to find the number
// of subsets with equal bitwise
// AND, OR and XOR values
  
 
import java.util.*;
 
class GFG{
static int mod = 1000000007;
  
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
static int countSubsets(int a[], int n)
{
    int answer = 0;
  
    // Precompute the modded powers
    // of two for subset counting
    int []powerOfTwo = new int[100005];
    powerOfTwo[0] = 1;
  
    // Loop to iterate and find the modded
    // powers of two for subset counting
    for (int i = 1; i < 100005; i++)
        powerOfTwo[i]
            = (powerOfTwo[i - 1] * 2)
              % mod;
  
    // Map to store the frequency of
    // each element
    HashMap frequency = new HashMap();
  
    // Loop to compute the frequency
    for (int i = 0; i < n; i++)
        if(frequency.containsKey(a[i])){
            frequency.put(a[i], frequency.get(a[i])+1);
        }else{
            frequency.put(a[i], 1);
    }
  
    // For every element > 0, the number of
    // subsets formed using this element only
    // is equal to 2 ^ (frequency[element]-1).
    // And for 0, we have to find all
    // the subsets, so 2^(frequency[element]) -1
    for (Map.Entry el : frequency.entrySet()) {
  
        // If element is greater than 0
        if (el.getKey() != 0)
            answer
                = (answer % mod
                   + powerOfTwo[el.getValue() - 1])
                  % mod;
  
        else
            answer
                = (answer % mod
                   + powerOfTwo[el.getValue()]
                   - 1 + mod)
                  % mod;
    }
    return answer;
}
  
// Driver code
public static void main(String[] args)
{
    int N = 6;
    int A[] = { 1, 3, 2, 1, 2, 1 };
  
    System.out.print(countSubsets(A, N));
  
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to find the number
# of subsets with equal bitwise
# AND, OR and XOR values
mod = 1000000007
 
# Function to find the number of
# subsets with equal bitwise AND,
# OR and XOR values
def countSubsets(a, n):
     
    answer = 0
     
    # Precompute the modded powers
    # of two for subset counting
    powerOfTwo = [0 for x in range(100005)]
    powerOfTwo[0] = 1
 
    # Loop to iterate and find the modded
    # powers of two for subset counting
    for i in range(1, 100005):
        powerOfTwo[i] = (powerOfTwo[i - 1] * 2) % mod
         
    # Map to store the frequency of
    # each element
    frequency = {}
     
    # Loop to compute the frequency
    for i in range(0, n):
        if a[i] in frequency:
            frequency[a[i]] += 1
        else:
            frequency[a[i]] = 1
             
    # For every element > 0, the number of
    # subsets formed using this element only
    # is equal to 2 ^ (frequency[element]-1).
    # And for 0, we have to find all
    # the subsets, so 2^(frequency[element]) -1
    for key, value in frequency.items():
         
        # If element is greater than 0
        if (key != 0):
            answer = (answer % mod +
                  powerOfTwo[value - 1]) % mod
        else:
            answer = (answer % mod +
                 powerOfTwo[value] - 1 + mod)% mod
                  
    return answer
 
# Driver code
N = 6
A = [ 1, 3, 2, 1, 2, 1 ]
 
print(countSubsets(A, N))
 
# This code is contributed by amreshkumar3


C#
// C# program to find the number
// of subsets with equal bitwise
// AND, OR and XOR values
using System;
using System.Collections.Generic;
 
class GFG{
     
static int mod = 1000000007;
 
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
static int countSubsets(int []a, int n)
{
    int answer = 0;
 
    // Precompute the modded powers
    // of two for subset counting
    int []powerOfTwo = new int[100005];
    powerOfTwo[0] = 1;
 
    // Loop to iterate and find the modded
    // powers of two for subset counting
    for(int i = 1; i < 100005; i++)
       powerOfTwo[i] = (powerOfTwo[i - 1] * 2) % mod;
 
    // Map to store the frequency
    // of each element
    Dictionary frequency = new Dictionary();
 
    // Loop to compute the frequency
    for(int i = 0; i < n; i++)
       if(frequency.ContainsKey(a[i]))
       {
           frequency[a[i]] = frequency[a[i]] + 1;
       }
       else
       {
           frequency.Add(a[i], 1);
       }
 
    // For every element > 0, the number of
    // subsets formed using this element only
    // is equal to 2 ^ (frequency[element]-1).
    // And for 0, we have to find all
    // the subsets, so 2^(frequency[element]) -1
    foreach (KeyValuePair el in frequency)
    {
         
        // If element is greater than 0
        if (el.Key != 0)
            answer = (answer % mod +
                      powerOfTwo[el.Value - 1]) % mod;
        else
            answer = (answer % mod +
                      powerOfTwo[el.Value] - 1 +
                      mod) % mod;
    }
    return answer;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 6;
    int []A = { 1, 3, 2, 1, 2, 1 };
 
    Console.Write(countSubsets(A, N));
}
}
 
// This code is contributed by Rajput-Ji


输出:
7

时间复杂度: O(N * 2 N )其中N是数组的大小。

高效方法:高效方法位于按位运算的属性后面。

  • 使用按位AND和按位OR的属性,可以说,如果a&b == a | b,则a等于b。因此,如果子集的AND和OR值相等,则子集的所有元素都相同(例如x)。因此AND和OR值等于x。
  • 由于所有子序列的值都彼此相等,因此XOR值出现两种情况:
    1. 子集大小为奇数:XOR值等于x。
    2. 子集大小为偶数:XOR值等于0。
  • 因此,从以上观察,我们可以得出结论,所有奇数大小的子序列/具有相等元素的子集都遵循该特性。
  • 除此之外,如果子集的所有元素均为0,则子集将遵循该属性(与子集大小无关)。因此,所有仅以0为元素的子集将被添加到答案中。
  • 如果某个元素的频率为K,则它可以形成的奇数子集的数量为2 K – 1 ,并且它可以形成的非空子集的总数为2 K – 1

下面是上述方法的实现:

C++

// C++ program to find the number
// of subsets with equal bitwise
// AND, OR and XOR values
 
#include 
using namespace std;
const int mod = 1000000007;
 
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
int countSubsets(int a[], int n)
{
    int answer = 0;
 
    // Precompute the modded powers
    // of two for subset counting
    int powerOfTwo[100005];
    powerOfTwo[0] = 1;
 
    // Loop to iterate and find the modded
    // powers of two for subset counting
    for (int i = 1; i < 100005; i++)
        powerOfTwo[i]
            = (powerOfTwo[i - 1] * 2)
              % mod;
 
    // Map to store the frequency of
    // each element
    unordered_map frequency;
 
    // Loop to compute the frequency
    for (int i = 0; i < n; i++)
        frequency[a[i]]++;
 
    // For every element > 0, the number of
    // subsets formed using this element only
    // is equal to 2 ^ (frequency[element]-1).
    // And for 0, we have to find all
    // the subsets, so 2^(frequency[element]) -1
    for (auto el : frequency) {
 
        // If element is greater than 0
        if (el.first != 0)
            answer
                = (answer % mod
                   + powerOfTwo[el.second - 1])
                  % mod;
 
        else
            answer
                = (answer % mod
                   + powerOfTwo[el.second]
                   - 1 + mod)
                  % mod;
    }
    return answer;
}
 
// Driver code
int main()
{
    int N = 6;
    int A[N] = { 1, 3, 2, 1, 2, 1 };
 
    cout << countSubsets(A, N);
 
    return 0;
}

Java

// Java program to find the number
// of subsets with equal bitwise
// AND, OR and XOR values
  
 
import java.util.*;
 
class GFG{
static int mod = 1000000007;
  
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
static int countSubsets(int a[], int n)
{
    int answer = 0;
  
    // Precompute the modded powers
    // of two for subset counting
    int []powerOfTwo = new int[100005];
    powerOfTwo[0] = 1;
  
    // Loop to iterate and find the modded
    // powers of two for subset counting
    for (int i = 1; i < 100005; i++)
        powerOfTwo[i]
            = (powerOfTwo[i - 1] * 2)
              % mod;
  
    // Map to store the frequency of
    // each element
    HashMap frequency = new HashMap();
  
    // Loop to compute the frequency
    for (int i = 0; i < n; i++)
        if(frequency.containsKey(a[i])){
            frequency.put(a[i], frequency.get(a[i])+1);
        }else{
            frequency.put(a[i], 1);
    }
  
    // For every element > 0, the number of
    // subsets formed using this element only
    // is equal to 2 ^ (frequency[element]-1).
    // And for 0, we have to find all
    // the subsets, so 2^(frequency[element]) -1
    for (Map.Entry el : frequency.entrySet()) {
  
        // If element is greater than 0
        if (el.getKey() != 0)
            answer
                = (answer % mod
                   + powerOfTwo[el.getValue() - 1])
                  % mod;
  
        else
            answer
                = (answer % mod
                   + powerOfTwo[el.getValue()]
                   - 1 + mod)
                  % mod;
    }
    return answer;
}
  
// Driver code
public static void main(String[] args)
{
    int N = 6;
    int A[] = { 1, 3, 2, 1, 2, 1 };
  
    System.out.print(countSubsets(A, N));
  
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python3 program to find the number
# of subsets with equal bitwise
# AND, OR and XOR values
mod = 1000000007
 
# Function to find the number of
# subsets with equal bitwise AND,
# OR and XOR values
def countSubsets(a, n):
     
    answer = 0
     
    # Precompute the modded powers
    # of two for subset counting
    powerOfTwo = [0 for x in range(100005)]
    powerOfTwo[0] = 1
 
    # Loop to iterate and find the modded
    # powers of two for subset counting
    for i in range(1, 100005):
        powerOfTwo[i] = (powerOfTwo[i - 1] * 2) % mod
         
    # Map to store the frequency of
    # each element
    frequency = {}
     
    # Loop to compute the frequency
    for i in range(0, n):
        if a[i] in frequency:
            frequency[a[i]] += 1
        else:
            frequency[a[i]] = 1
             
    # For every element > 0, the number of
    # subsets formed using this element only
    # is equal to 2 ^ (frequency[element]-1).
    # And for 0, we have to find all
    # the subsets, so 2^(frequency[element]) -1
    for key, value in frequency.items():
         
        # If element is greater than 0
        if (key != 0):
            answer = (answer % mod +
                  powerOfTwo[value - 1]) % mod
        else:
            answer = (answer % mod +
                 powerOfTwo[value] - 1 + mod)% mod
                  
    return answer
 
# Driver code
N = 6
A = [ 1, 3, 2, 1, 2, 1 ]
 
print(countSubsets(A, N))
 
# This code is contributed by amreshkumar3

C#

// C# program to find the number
// of subsets with equal bitwise
// AND, OR and XOR values
using System;
using System.Collections.Generic;
 
class GFG{
     
static int mod = 1000000007;
 
// Function to find the number of
// subsets with equal bitwise AND,
// OR and XOR values
static int countSubsets(int []a, int n)
{
    int answer = 0;
 
    // Precompute the modded powers
    // of two for subset counting
    int []powerOfTwo = new int[100005];
    powerOfTwo[0] = 1;
 
    // Loop to iterate and find the modded
    // powers of two for subset counting
    for(int i = 1; i < 100005; i++)
       powerOfTwo[i] = (powerOfTwo[i - 1] * 2) % mod;
 
    // Map to store the frequency
    // of each element
    Dictionary frequency = new Dictionary();
 
    // Loop to compute the frequency
    for(int i = 0; i < n; i++)
       if(frequency.ContainsKey(a[i]))
       {
           frequency[a[i]] = frequency[a[i]] + 1;
       }
       else
       {
           frequency.Add(a[i], 1);
       }
 
    // For every element > 0, the number of
    // subsets formed using this element only
    // is equal to 2 ^ (frequency[element]-1).
    // And for 0, we have to find all
    // the subsets, so 2^(frequency[element]) -1
    foreach (KeyValuePair el in frequency)
    {
         
        // If element is greater than 0
        if (el.Key != 0)
            answer = (answer % mod +
                      powerOfTwo[el.Value - 1]) % mod;
        else
            answer = (answer % mod +
                      powerOfTwo[el.Value] - 1 +
                      mod) % mod;
    }
    return answer;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 6;
    int []A = { 1, 3, 2, 1, 2, 1 };
 
    Console.Write(countSubsets(A, N));
}
}
 
// This code is contributed by Rajput-Ji
输出:
7

时间复杂度: O(N) ,其中N是数组的大小。