📜  数组中每个无序对的成对和的异或

📅  最后修改于: 2021-10-25 06:50:23             🧑  作者: Mango

给定一个长度为N的数组arr[] ,任务是找到数组的每个可能的无序对的成对和的异或。无序对总和定义如下 –

XOR of pairwise sum  = (A[0] + A[1]) ^
    (A[0] + A[2]) ^ ...(A[0] + A[N]) ^
    (A[1] + A[2]) ^ ...(A[1] + A[N]) ^
    .......
    (A[N-1] + A[N])

Notice that after including A[0] and A[1] 
as pairs, then A[1] and A[0] are not included.

例子:

朴素的方法:这个想法是在两个循环的帮助下找到每个可能的无序对,并找到这些对的异或。
下面是上述方法的实现:

C++
// C++ implementation to find XOR of
// pairwise sum of every unordered
// pairs in an array
 
#include 
 
using namespace std;
 
// Function to find XOR of pairwise
// sum of every unordered pairs
int xorOfSum(int a[], int n)
{
    int answer = 0;
     
    // Loop to choose every possible
    // pairs in the array
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++)
            answer ^= (a[i] + a[j]);
    }
 
    return answer;
}
 
// Driver Code
int main()
{
    int n = 3;
    int A[n] = { 1, 2, 3 };
 
    cout << xorOfSum(A, n);
    return 0;
}


Java
// Java implementation to find XOR of
// pairwise sum of every unordered
// pairs in an array
class GFG{
  
// Function to find XOR of pairwise
// sum of every unordered pairs
static int xorOfSum(int a[], int n)
{
    int answer = 0;
      
    // Loop to choose every possible
    // pairs in the array
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++)
            answer ^= (a[i] + a[j]);
    }
  
    return answer;
}
  
// Driver Code
public static void main(String[] args)
{
    int n = 3;
    int A[] = { 1, 2, 3 };
  
    System.out.print(xorOfSum(A, n));
}
}
 
// This code is contributed by PrinciRaj1992


Python3
# Python3 implementation to find XOR of
# pairwise sum of every unordered
# pairs in an array
 
# Function to find XOR of pairwise
# sum of every unordered pairs
def xorOfSum(a, n):
    answer = 0
 
    # Loop to choose every possible
    # pairs in the array
    for i in range(n):
        for j in range(i + 1, n):
            answer ^= (a[i] + a[j])
 
    return answer
 
# Driver Code
if __name__ == '__main__':
    n = 3
    A=[1, 2, 3]
 
    print(xorOfSum(A, n))
 
# This code is contributed by mohit kumar 29


C#
// C# implementation to find XOR of
// pairwise sum of every unordered
// pairs in an array
using System;
using System.Collections.Generic;
 
class GFG{
   
// Function to find XOR of pairwise
// sum of every unordered pairs
static int xorOfSum(int []a, int n)
{
    int answer = 0;
       
    // Loop to choose every possible
    // pairs in the array
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++)
            answer ^= (a[i] + a[j]);
    }
   
    return answer;
}
   
// Driver Code
public static void Main(String[] args)
{
    int n = 3;
    int []A = { 1, 2, 3 };
   
    Console.Write(xorOfSum(A, n));
}
}
  
// This code is contributed by PrinciRaj1992


Javascript


C++
// C++ implementation to find XOR of
// pairwise sum of every unordered
// pairs in an array
 
#include 
 
using namespace std;
 
// Function to find XOR of pairwise
// sum of every unordered pairs
int xorOfSum(int a[], int n)
{
 
    int i, j, k;
     
    // Sort the array
    sort(a, a + n);
 
    int ans = 0;
 
    // Array elements are not greater
    // than 1e7 so 27 bits are suffice
    for (k = 0; k < 27; ++k) {
         
        // Modded elements of array
        vector b(n);
         
        // Loop to find the modded
        // elements of array
        for (i = 0; i < n; i++)
            b[i] = a[i] % (1 << (k + 1));
 
        // Sort the modded array
        sort(b.begin(), b.end());
 
        int cnt = 0;
        for (i = 0; i < n; i++) {
            // finding the bound for j
            // for given i using binary search
            int l = lower_bound(b.begin() +
                           i + 1, b.end(),
               (1 << k) - b[i]) - b.begin();
            int r = lower_bound(b.begin() +
                    i + 1, b.end(), (1 << (k + 1)) -
                          b[i]) - b.begin();
 
            // All the numbers in the range
            // of indices can be added to the
            // count to check the xor.
            cnt += r - l;
 
            l = lower_bound(b.begin() + i + 1,
                 b.end(), (1 << (k + 1)) +
                 (1 << k) - b[i]) - b.begin();
            cnt += n - l;
        }
        // Remainder of cnt * kth power
        // of 2 added to the xor value
        ans += (cnt % 2) * 1LL * (1 << k);
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int n = 3;
    int A[n] = { 1, 2, 3 };
 
    cout << xorOfSum(A, n);
    return 0;
}


输出:
2

有效的方法:

  • 为了获得ķ我们在所有对和数看到最后的异或值的位,即k位他们设置与否。如果有,甚至一些有K位设置,则k位对,他们的XOR为零别的一个。
  • 为了找到设置了K 位的对和的计数,我们注意到我们可以将所有数组元素乘以 2 (K+1) 。这是因为 X 和 Y 属于输入数组并且Sum = X + Y 。然后 X + Y 可以加起来设置它们的K 位,这意味着 Sum >= 2 K 。它也可以被观察到,它们可以具有从另外一个遗留,这使得数字在范围[2(K + 1),2(K + 1)+ 2 K)具有其K位未设置。所以,我们只关心K和(K + 1)的所有号码的位检查K的XOR位。
  • 执行模运算后,对于设置第 k 位的 sum,其值将在范围内 – [2 K , 2 (K+1) ) U [2 (K+1) + 2 K , Max-Value-Sum -可以采取 ]。
  • 要查找所述范围内的数字,请创建另一个包含 arr[] 修改后的数组元素的数组 B,并对它们进行排序。那么 Sum 可以假设为 Sum = B i + B j 。最后,使用二分查找(C++ 内置的lower_bound)找到j 的最大边界。修复 i 并且由于数组已排序,因此找到满足给定条件的最后一个 j,并且可以将索引范围内的所有数字添加到计数中以检查异或。

下面是上述方法的实现:

C++

// C++ implementation to find XOR of
// pairwise sum of every unordered
// pairs in an array
 
#include 
 
using namespace std;
 
// Function to find XOR of pairwise
// sum of every unordered pairs
int xorOfSum(int a[], int n)
{
 
    int i, j, k;
     
    // Sort the array
    sort(a, a + n);
 
    int ans = 0;
 
    // Array elements are not greater
    // than 1e7 so 27 bits are suffice
    for (k = 0; k < 27; ++k) {
         
        // Modded elements of array
        vector b(n);
         
        // Loop to find the modded
        // elements of array
        for (i = 0; i < n; i++)
            b[i] = a[i] % (1 << (k + 1));
 
        // Sort the modded array
        sort(b.begin(), b.end());
 
        int cnt = 0;
        for (i = 0; i < n; i++) {
            // finding the bound for j
            // for given i using binary search
            int l = lower_bound(b.begin() +
                           i + 1, b.end(),
               (1 << k) - b[i]) - b.begin();
            int r = lower_bound(b.begin() +
                    i + 1, b.end(), (1 << (k + 1)) -
                          b[i]) - b.begin();
 
            // All the numbers in the range
            // of indices can be added to the
            // count to check the xor.
            cnt += r - l;
 
            l = lower_bound(b.begin() + i + 1,
                 b.end(), (1 << (k + 1)) +
                 (1 << k) - b[i]) - b.begin();
            cnt += n - l;
        }
        // Remainder of cnt * kth power
        // of 2 added to the xor value
        ans += (cnt % 2) * 1LL * (1 << k);
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int n = 3;
    int A[n] = { 1, 2, 3 };
 
    cout << xorOfSum(A, n);
    return 0;
}
输出:
2

性能分析:

  • 时间复杂度: O(N * log(max(A))*log(N)

最外层循环运行 log(max(A)) 次,对于每个循环,我们创建和排序数组 b ,它由N 个元素组成,因此复杂度为O(N*log(N)*log(max(A)))