Search code examples
arraysalgorithmbit-manipulationbitwise-operators

bitwise array manipulation


You are given an array A containing N positive integers (1 <= A[i] <= 10^9)

Let F(i,j,k) = ( A[i] | A[j] ) & A[k]
| represents bitwise OR and & represents bitwise AND
The task is to determine the bitwise XOR of F(A,B,C) over all triplets (A,B,C) such that 1<= A,B,C <=N

for Example:
if N=2 and A=[1,4]
triplets will be:

  • F(1,1,1) = 1
  • F(1,1,2) = 0
  • F(1,2,1) = 1
  • F(1,2,2) = 4
  • F(2,1,1) = 1
  • F(2,1,2) = 4
  • F(2,2,1) = 0
  • F(2,2,2) = 4
    Bitwise XOR of all = 1^0^1^4^1^4^0^4 = 5
    so the answer is 5.

one more example:
if A=[14,9,19,18,17,11,12] answer=16

How to solve this question or how to proceed with such questions?
Code in javascript would be helpful, but other languages are also welcome.


Solution

  • These kinds of questions can be solved by considering each bit separately.

    For each bit, let n0 be the number of array elements that have that bit set to 0, and let n1 be the number of elements that have that bit set to 1.

    Then it's easy to determine whether or not that bit is set in the answer:

    • The number of pairs i,j such that the bit is set in A[i]|A[j] is n1*n1 + n1*n0*2
    • The number of triplets i,j,k with that bit set in F(i,j,k) is then n1*(n1*n1 + n1*n0*2)
    • Since all the F's are XORed together, the result will have the bit set if it's set in an odd number of triplets, i.e., if the above expression evaluates to an odd number.

    At this point, we could easily solve the problem by counting the 1s and 0s for each bit, but notice that n1*(n1*n1 + n1*n0*2) evaluates to an odd number exactly when n1 is odd, i.e., when the bit appears an odd number of times in the array. To get a number with each bit set if it's set an odd number of times in the array...

    just XOR all the array elements together.