📜  使得(Ai&Aj)= 0的有序对的数量

📅  最后修改于: 2021-05-04 17:35:08             🧑  作者: Mango

给定n个整数的数组A [],找出有序对的数量,使得A i &A j为零,其中0 <=(i,j)限制条件:
1 <= n <= 10 4
1 <= A i <= 10 4
例子:

Input : A[] = {3, 4, 2}
Output : 4
Explanation : The pairs are (3, 4) and (4, 2) which are 
counted as 2 as (4, 3) and (2, 4) are considered different. 

Input : A[]={5, 4, 1, 6}
Output : 4 
Explanation : (4, 1), (1, 4), (6, 1) and (1, 6) are the pairs

简单方法:一种简单方法是检查所有可能的对,并计算按位&返回0的有序对的数量。
下面是上述想法的实现:

C++
// CPP program to calculate the number
// of ordered pairs such that their bitwise
// and is zero
#include 
using namespace std;
  
// Naive function to count the number
// of ordered pairs such that their
// bitwise and is 0
int countPairs(int a[], int n)
{
    int count = 0;
  
    // check for all possible pairs
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++)
            if ((a[i] & a[j]) == 0)
  
                // add 2 as (i, j) and (j, i) are 
                // considered different
                count += 2; 
    }
  
    return count;
}
  
// Driver Code
int main()
{
    int a[] = { 3, 4, 2 };
    int n = sizeof(a) / sizeof(a[0]);    
    cout << countPairs(a, n);    
    return 0;
}


Java
// Java program to calculate the number
// of ordered pairs such that their bitwise
// and is zero
  
class GFG {
      
    // Naive function to count the number
    // of ordered pairs such that their
    // bitwise and is 0
    static int countPairs(int a[], int n)
    {
        int count = 0;
  
        // check for all possible pairs
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++)
                if ((a[i] & a[j]) == 0)
  
                    // add 2 as (i, j) and (j, i) are
                    // considered different
                    count += 2;
        }
  
        return count;
    }
  
    // Driver Code
    public static void main(String arg[])
    {
        int a[] = { 3, 4, 2 };
        int n = a.length;
        System.out.print(countPairs(a, n));
    }
}
  
// This code is contributed by Anant Agarwal.


Python3
# Python3 program to calculate the number
# of ordered pairs such that their
# bitwise and is zero
  
# Naive function to count the number
# of ordered pairs such that their
# bitwise and is 0
def countPairs(a, n):
    count = 0
  
    # check for all possible pairs
    for i in range(0, n):
        for j in range(i + 1, n):
            if (a[i] & a[j]) == 0:
  
                # add 2 as (i, j) and (j, i) are 
                # considered different
                count += 2 
    return count
  
# Driver Code
a = [ 3, 4, 2 ]
n = len(a) 
print (countPairs(a, n)) 
  
# This code is contributed
# by Shreyanshi Arun.


C#
// C# program to calculate the number
// of ordered pairs such that their 
// bitwise and is zero
using System;
  
class GFG {
      
    // Naive function to count the number
    // of ordered pairs such that their
    // bitwise and is 0
    static int countPairs(int []a, int n)
    {
        int count = 0;
  
        // check for all possible pairs
        for (int i = 0; i < n; i++) 
        {
            for (int j = i + 1; j < n; j++)
                if ((a[i] & a[j]) == 0)
  
                    // add 2 as (i, j) and (j, i) 
                    // arev considered different
                    count += 2;
        }
  
        return count;
    }
  
    // Driver Code
    public static void Main()
    {
        int []a = { 3, 4, 2 };
        int n = a.Length;
        Console.Write(countPairs(a, n));
    }
}
  
// This code is contributed by nitin mittal.


PHP


C++
// CPP program to calculate the number
// of ordered pairs such that their bitwise
// and is zero
  
#include 
using namespace std;
  
const int N = 15;
  
// efficient function to count pairs
long long countPairs(int a[], int n)
{
    // stores the frequency of each number
    unordered_map hash;
  
    long long dp[1 << N][N + 1];
      
    memset(dp, 0, sizeof(dp)); // initialize 0 to all
  
    // count the frequency of every element
    for (int i = 0; i < n; ++i)
        hash[a[i]] += 1;
  
    // iterate for al possible values that a[i] can be
    for (long long mask = 0; mask < (1 << N); ++mask) {
  
        // if the last bit is ON
        if (mask & 1)
            dp[mask][0] = hash[mask] + hash[mask ^ 1];
        else // is the last bit is OFF
            dp[mask][0] = hash[mask];
  
        // iterate till n
        for (int i = 1; i <= N; ++i) {
  
            // if mask's ith bit is set
            if (mask & (1 << i))
            {
                dp[mask][i] = dp[mask][i - 1] + 
                        dp[mask ^ (1 << i)][i - 1];
            }    
            else // if mask's ith bit is not set
                dp[mask][i] = dp[mask][i - 1];
        }
    }
  
    long long ans = 0;
  
    // iterate for all the array element
    // and count the number of pairs
    for (int i = 0; i < n; i++)
        ans += dp[((1 << N) - 1) ^ a[i]][N];
  
    // return answer
    return ans;
}
  
// Driver Code
int main()
{
    int a[] = { 5, 4, 1, 6 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << countPairs(a, n);
    return 0;
}


Java
// Java program to calculate 
// the number of ordered pairs 
// such that their bitwise 
// and is zero 
import java.util.*;
class GFG{
      
static int N = 15; 
    
// Efficient function to count pairs 
public static int countPairs(int a[], 
                             int n) 
{ 
  // Stores the frequency of 
  // each number 
  HashMap hash = new HashMap<>();
  
  int dp[][] = new int[1 << N][N + 1]; 
  
  // Initialize 0 to all 
    
  // Count the frequency 
  // of every element 
  for (int i = 0; i < n; ++i) 
  {
    if(hash.containsKey(a[i]))
    {
      hash.replace(a[i], 
      hash.get(a[i]) + 1);
    }
    else
    {
      hash.put(a[i], 1);
    }
  }
  
  // Iterate for al possible 
  // values that a[i] can be 
  for (int mask = 0; 
           mask < (1 << N); ++mask) 
  {
    // If the last bit is ON 
    if ((mask & 1) != 0) 
    {
      if(hash.containsKey(mask))
      {
        dp[mask][0] = hash.get(mask);
      }
      if(hash.containsKey(mask ^ 1))
      {
        dp[mask][0] += hash.get(mask ^ 1);
      }
    }
    else
    {
      // is the last bit is OFF 
      if(hash.containsKey(mask))
      {
        dp[mask][0] = hash.get(mask);  
      }
    } 
  
    // Iterate till n 
    for (int i = 1; i <= N; ++i) 
    { 
      // If mask's ith bit is set 
      if ((mask & (1 << i)) != 0) 
      { 
        dp[mask][i] = dp[mask][i - 1] + 
                      dp[mask ^ (1 << i)][i - 1]; 
      }     
      else
      {
        // If mask's ith bit is not set 
        dp[mask][i] = dp[mask][i - 1]; 
      } 
    } 
  } 
  
  int ans = 0; 
  
  // Iterate for all the 
  // array element and 
  // count the number of pairs 
  for (int i = 0; i < n; i++) 
  {
    ans += dp[((1 << N) - 1) ^ a[i]][N]; 
  }
  
  // return answer 
  return ans; 
} 
  
// Driver code    
public static void main(String[] args) 
{
  int a[] = {5, 4, 1, 6}; 
  int n = a.length; 
  System.out.print(countPairs(a, n)); 
}
}
  
// This code is contributed by divyeshrabadiya07


Python3
# Python program to calculate the number
# of ordered pairs such that their bitwise
# and is zero
N = 15
  
# efficient function to count pairs
def countPairs(a, n):
  
    # stores the frequency of each number
    Hash = {}
      
    # initialize 0 to all
    dp = [[0 for i in range(N + 1)] for j in range(1 << N)]
  
    # count the frequency of every element
    for i in range(n):
        if a[i] not in Hash:
            Hash[a[i]] = 1
        else:
            Hash[a[i]] += 1
  
    # iterate for al possible values that a[i] can be
    mask = 0
    while(mask < (1 << N)):
        if mask not in Hash:
            Hash[mask] = 0
  
        # if the last bit is ON
        if(mask & 1):
            dp[mask][0] = Hash[mask] + Hash[mask ^ 1]
              
        else:    # is the last bit is OFF
            dp[mask][0] = Hash[mask]
  
        # iterate till n
        for i in range(1, N + 1):
  
            # if mask's ith bit is set
            if(mask & (1 << i)):
                dp[mask][i] = dp[mask][i - 1] + dp[mask ^ (1 << i)][i - 1]
                  
            else:    # if mask's ith bit is not set
                dp[mask][i] = dp[mask][i - 1]
  
        mask += 1
  
    ans = 0
      
    # iterate for all the array element
    # and count the number of pairs
    for i in range(n):
        ans += dp[((1 << N) - 1) ^ a[i]][N]
          
    # return answer
    return ans
  
# Driver Code
a = [5, 4, 1, 6]
n = len(a)
print(countPairs(a, n))
  
# This code is contributed by avanitrachhadiya2155


C#
// C# program to calculate 
// the number of ordered pairs 
// such that their bitwise 
// and is zero 
using System;
using System.Collections.Generic;
  
class GFG {
      
    static int N = 15; 
     
    // Efficient function to count pairs 
    static int countPairs(int[] a, int n) 
    { 
      // Stores the frequency of 
      // each number 
      Dictionary hash = new Dictionary();
       
      int[, ] dp = new int[1 << N, N + 1]; 
       
      // Initialize 0 to all 
         
      // Count the frequency 
      // of every element 
      for (int i = 0; i < n; ++i) 
      {
        if(hash.ContainsKey(a[i]))
        {
          hash[a[i]] += 1;
        }
        else
        {
          hash.Add(a[i], 1);
        }
      }
       
      // Iterate for al possible 
      // values that a[i] can be 
      for (int mask = 0; 
               mask < (1 << N); ++mask) 
      {
        // If the last bit is ON 
        if ((mask & 1) != 0) 
        {
          if(hash.ContainsKey(mask))
          {
            dp[mask, 0] = hash[mask];
          }
          if(hash.ContainsKey(mask ^ 1))
          {
            dp[mask, 0] += hash[mask ^ 1];
          }
        }
        else
        {
          // is the last bit is OFF 
          if(hash.ContainsKey(mask))
          {
            dp[mask, 0] = hash[mask];  
          }
        } 
       
        // Iterate till n 
        for (int i = 1; i <= N; ++i) 
        { 
            
          // If mask's ith bit is set 
          if ((mask & (1 << i)) != 0) 
          { 
            dp[mask, i] = dp[mask, i - 1] + 
                          dp[mask ^ (1 << i), i - 1]; 
          }     
          else
          {
              
            // If mask's ith bit is not set 
            dp[mask, i] = dp[mask, i - 1]; 
          } 
        } 
      } 
       
      int ans = 0; 
       
      // Iterate for all the 
      // array element and 
      // count the number of pairs 
      for (int i = 0; i < n; i++) 
      {
        ans += dp[((1 << N) - 1) ^ a[i], N]; 
      }
       
      // return answer 
      return ans; 
    } 
     
  // Driver code
  static void Main() 
  {
      int[] a = {5, 4, 1, 6}; 
      int n = a.Length; 
      Console.WriteLine(countPairs(a, n)); 
  }
}
  
// This code is contributed by divyesh072019


输出:

4

时间复杂度: O(n 2 )
高效的方法:一种有效的方法是使用“子集总和动态规划”方法并计算有序对的数量。在SOS DP中,我们找出按位并返回0的对。在这里,我们需要计算对的数量。
一些关键的观察是约束,数组元素可以为10 4的最大值。计算掩码最大为(1 << 15)将为我们提供答案。使用哈希计算每个元素的出现次数。如果最后一位为OFF,则与SOS dp有关,因为只有一种可能的OFF位,所以我们有一个基本情况。

dp[mask][0] = freq(mask)

如果最后一位设置为ON,则基本情况如下:

dp[mask][0] = freq(mask) + freq(mask^1)

我们添加freq(mask ^ 1)来添加OFF位的另一种可能性。
迭代N = 15位,这是可能的最大值。
让我们考虑第i位为0 ,则第i位的子集与掩码没有区别,因为这意味着数字在第i位为1,掩码为0,这意味着它不是掩码的子集。因此,我们得出的结论是,这些数字现在仅在前(i-1)位不同。因此,

DP(mask, i) = DP(mask, i-1)

现在,第二种情况,如果第i位为1,则可以将其分为两个不相交的集合。一个包含第i位为1的数字,与下一个(i-1)位的掩码不同。第二个包含第i位为0且与掩码不同的数字

\oplus

下(i-1)位中的(2 i )。因此,

DP(mask, i) = DP(mask, i-1) + DP(mask
*** QuickLaTeX cannot compile formula:
 

*** Error message:
Error: Nothing to show, formula is empty
2i, i-1).

DP [mask] [i]存储仅在前i位与mask不同的mask的子集数量。对所有数组元素进行迭代,并为每个数组元素将子集数(dp [((1 << N -1 – 1)^ a [i]] [N])添加到对数中。 N =最大位数。
将dp [(((1 << N)– 1)^ a [i]] [N]添加到对数的说明:以A [i]为5的例子为例,二进制为101。为了更好地理解,假设在这种情况下N = 3,因此,将101的反向值设为010,这将按位应用并给出0。因此(1 << 3)得出1000,而从1减去后得出111。111

\oplus

101给出010,这是反转的位。因此dp [(((1 << N)-1)^ a [i]] [N]的子集数量将在按位&运算符返回0。
下面是上述想法的实现:

C++

// CPP program to calculate the number
// of ordered pairs such that their bitwise
// and is zero
  
#include 
using namespace std;
  
const int N = 15;
  
// efficient function to count pairs
long long countPairs(int a[], int n)
{
    // stores the frequency of each number
    unordered_map hash;
  
    long long dp[1 << N][N + 1];
      
    memset(dp, 0, sizeof(dp)); // initialize 0 to all
  
    // count the frequency of every element
    for (int i = 0; i < n; ++i)
        hash[a[i]] += 1;
  
    // iterate for al possible values that a[i] can be
    for (long long mask = 0; mask < (1 << N); ++mask) {
  
        // if the last bit is ON
        if (mask & 1)
            dp[mask][0] = hash[mask] + hash[mask ^ 1];
        else // is the last bit is OFF
            dp[mask][0] = hash[mask];
  
        // iterate till n
        for (int i = 1; i <= N; ++i) {
  
            // if mask's ith bit is set
            if (mask & (1 << i))
            {
                dp[mask][i] = dp[mask][i - 1] + 
                        dp[mask ^ (1 << i)][i - 1];
            }    
            else // if mask's ith bit is not set
                dp[mask][i] = dp[mask][i - 1];
        }
    }
  
    long long ans = 0;
  
    // iterate for all the array element
    // and count the number of pairs
    for (int i = 0; i < n; i++)
        ans += dp[((1 << N) - 1) ^ a[i]][N];
  
    // return answer
    return ans;
}
  
// Driver Code
int main()
{
    int a[] = { 5, 4, 1, 6 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << countPairs(a, n);
    return 0;
}

Java

// Java program to calculate 
// the number of ordered pairs 
// such that their bitwise 
// and is zero 
import java.util.*;
class GFG{
      
static int N = 15; 
    
// Efficient function to count pairs 
public static int countPairs(int a[], 
                             int n) 
{ 
  // Stores the frequency of 
  // each number 
  HashMap hash = new HashMap<>();
  
  int dp[][] = new int[1 << N][N + 1]; 
  
  // Initialize 0 to all 
    
  // Count the frequency 
  // of every element 
  for (int i = 0; i < n; ++i) 
  {
    if(hash.containsKey(a[i]))
    {
      hash.replace(a[i], 
      hash.get(a[i]) + 1);
    }
    else
    {
      hash.put(a[i], 1);
    }
  }
  
  // Iterate for al possible 
  // values that a[i] can be 
  for (int mask = 0; 
           mask < (1 << N); ++mask) 
  {
    // If the last bit is ON 
    if ((mask & 1) != 0) 
    {
      if(hash.containsKey(mask))
      {
        dp[mask][0] = hash.get(mask);
      }
      if(hash.containsKey(mask ^ 1))
      {
        dp[mask][0] += hash.get(mask ^ 1);
      }
    }
    else
    {
      // is the last bit is OFF 
      if(hash.containsKey(mask))
      {
        dp[mask][0] = hash.get(mask);  
      }
    } 
  
    // Iterate till n 
    for (int i = 1; i <= N; ++i) 
    { 
      // If mask's ith bit is set 
      if ((mask & (1 << i)) != 0) 
      { 
        dp[mask][i] = dp[mask][i - 1] + 
                      dp[mask ^ (1 << i)][i - 1]; 
      }     
      else
      {
        // If mask's ith bit is not set 
        dp[mask][i] = dp[mask][i - 1]; 
      } 
    } 
  } 
  
  int ans = 0; 
  
  // Iterate for all the 
  // array element and 
  // count the number of pairs 
  for (int i = 0; i < n; i++) 
  {
    ans += dp[((1 << N) - 1) ^ a[i]][N]; 
  }
  
  // return answer 
  return ans; 
} 
  
// Driver code    
public static void main(String[] args) 
{
  int a[] = {5, 4, 1, 6}; 
  int n = a.length; 
  System.out.print(countPairs(a, n)); 
}
}
  
// This code is contributed by divyeshrabadiya07

Python3

# Python program to calculate the number
# of ordered pairs such that their bitwise
# and is zero
N = 15
  
# efficient function to count pairs
def countPairs(a, n):
  
    # stores the frequency of each number
    Hash = {}
      
    # initialize 0 to all
    dp = [[0 for i in range(N + 1)] for j in range(1 << N)]
  
    # count the frequency of every element
    for i in range(n):
        if a[i] not in Hash:
            Hash[a[i]] = 1
        else:
            Hash[a[i]] += 1
  
    # iterate for al possible values that a[i] can be
    mask = 0
    while(mask < (1 << N)):
        if mask not in Hash:
            Hash[mask] = 0
  
        # if the last bit is ON
        if(mask & 1):
            dp[mask][0] = Hash[mask] + Hash[mask ^ 1]
              
        else:    # is the last bit is OFF
            dp[mask][0] = Hash[mask]
  
        # iterate till n
        for i in range(1, N + 1):
  
            # if mask's ith bit is set
            if(mask & (1 << i)):
                dp[mask][i] = dp[mask][i - 1] + dp[mask ^ (1 << i)][i - 1]
                  
            else:    # if mask's ith bit is not set
                dp[mask][i] = dp[mask][i - 1]
  
        mask += 1
  
    ans = 0
      
    # iterate for all the array element
    # and count the number of pairs
    for i in range(n):
        ans += dp[((1 << N) - 1) ^ a[i]][N]
          
    # return answer
    return ans
  
# Driver Code
a = [5, 4, 1, 6]
n = len(a)
print(countPairs(a, n))
  
# This code is contributed by avanitrachhadiya2155

C#

// C# program to calculate 
// the number of ordered pairs 
// such that their bitwise 
// and is zero 
using System;
using System.Collections.Generic;
  
class GFG {
      
    static int N = 15; 
     
    // Efficient function to count pairs 
    static int countPairs(int[] a, int n) 
    { 
      // Stores the frequency of 
      // each number 
      Dictionary hash = new Dictionary();
       
      int[, ] dp = new int[1 << N, N + 1]; 
       
      // Initialize 0 to all 
         
      // Count the frequency 
      // of every element 
      for (int i = 0; i < n; ++i) 
      {
        if(hash.ContainsKey(a[i]))
        {
          hash[a[i]] += 1;
        }
        else
        {
          hash.Add(a[i], 1);
        }
      }
       
      // Iterate for al possible 
      // values that a[i] can be 
      for (int mask = 0; 
               mask < (1 << N); ++mask) 
      {
        // If the last bit is ON 
        if ((mask & 1) != 0) 
        {
          if(hash.ContainsKey(mask))
          {
            dp[mask, 0] = hash[mask];
          }
          if(hash.ContainsKey(mask ^ 1))
          {
            dp[mask, 0] += hash[mask ^ 1];
          }
        }
        else
        {
          // is the last bit is OFF 
          if(hash.ContainsKey(mask))
          {
            dp[mask, 0] = hash[mask];  
          }
        } 
       
        // Iterate till n 
        for (int i = 1; i <= N; ++i) 
        { 
            
          // If mask's ith bit is set 
          if ((mask & (1 << i)) != 0) 
          { 
            dp[mask, i] = dp[mask, i - 1] + 
                          dp[mask ^ (1 << i), i - 1]; 
          }     
          else
          {
              
            // If mask's ith bit is not set 
            dp[mask, i] = dp[mask, i - 1]; 
          } 
        } 
      } 
       
      int ans = 0; 
       
      // Iterate for all the 
      // array element and 
      // count the number of pairs 
      for (int i = 0; i < n; i++) 
      {
        ans += dp[((1 << N) - 1) ^ a[i], N]; 
      }
       
      // return answer 
      return ans; 
    } 
     
  // Driver code
  static void Main() 
  {
      int[] a = {5, 4, 1, 6}; 
      int n = a.Length; 
      Console.WriteLine(countPairs(a, n)); 
  }
}
  
// This code is contributed by divyesh072019

输出:

4

时间复杂度: O(N * 2 N )其中N = 15,这是最大可能位数,因为A max = 10 4