按位数组操作

bitwise array manipulation

给你一个包含N个正整数的数组A(1 <= A[i] <= 10^9)

令 F(i,j,k) = ( A[i] | A[j] ) & A[k]
|表示按位或 & 表示按位与
任务是确定 F(A,B,C) 在所有三元组 (A,B,C) 上的按位异或,使得 1<= A,B,C <=N

例如:
如果 N=2 且 A=[1,4]
三胞胎将是:

再举一个例子:
如果 A=[14,9,19,18,17,11,12] 答案=16

如何解决这个问题或如何处理此类问题?
javascript 中的代码会有所帮助,但也欢迎使用其他语言。

这些问题可以通过对每一位单独考虑来解决。

对于每一位,令 n0 为该位设置为 0 的数组元素的数量,并令 n1 为该位设置为 1 的元素的数量。

然后很容易确定答案中是否设置了该位:

  • A[i]|A[j] 中设置位的 i,j 对数是 n1*n1 + n1*n0*2
  • 在 F(i,j,k) 中设置该位的三元组数 i,j,k 则为 n1*(n1*n1 + n1*n0*2)
  • 由于所有的 F 都被异或在一起,如果它被设置为奇数个三元组,即如果上述表达式的计算结果为奇数,结果将设置位。

此时,我们可以通过计算每个位的 1 和 0 来轻松解决问题,但请注意,当 n1 为奇数时,n1*(n1*n1 + n1*n0*2) 计算为奇数,即,当该位在数组中出现奇数次时。如果在数组中设置了奇数次,则要获取每个位设置的数字...

只需将所有数组元素异或在一起

@Matt 的第一个解决方案非常好。这是另一个使用简单数学技巧的解决方案。

下面异或用和表示法,&用乘积表示法。

问题是计算F = sum F(i, j, k) = sum_{i, j, k} (A[i]|A[j]).A[k].

通过使用乘法 (&) 对加法 (xor) 的分配 属性,我们得到:

F = sum_k A[k] . sum_{i, j} (A[i] | A[j])

我们注意到

A[i] | A[j] = A[i] + A[j] + A[i].A[j]

然后

sum_{i, j} (A[i] | A[j]) = sum_{i, j} (A[i] + A[j] + A[i].A[j])

A + A = 0,显然sum_{i, j} (A[i] + A[j] = 0

此外,if (i != j), A[i].A[j] + A[j].A[i] = 0。因此,

sum_{i, j} A[i].A[j] = sum_i A[i].A[i] = sum_i A[i]

我们这里用的是A & A = A.

最后,

F = sum_k A[k] . sum_k A[k] = sum_k A[k]

解决方法是对数组中的所有元素进行异或。