使用给定Xor查找子集的编号

时间:2015-12-07 15:16:54

标签: algorithm data-structures xor

我有一个包含10 ^ 5个元素的数组,其中每个元素都在[0,1023]中。 我必须找到一个数组的子集数,使得元素的XOR是Q.(对于Q> 1023,答案是0)。 我想出了这个 O(N * 1024)方法

for (int i = 1; i <= n; i++ )
{
    int a = F[i]; 
    for (int j = 0; j < 1024; j++ )
    {
        ways[i][j] = ways[i-1][j] + ways[i-1][j^a];
        if (ways[i][j] >= mod) 
            ways[i][j] -= mod;
    }
}

由于元素的范围最高为1023,我可以维护一个Frequency F[i] ,数组,将上述代码减少到 O(1024 * 1024)。 这可能吗,频率数组可能有用吗?

1 个答案:

答案 0 :(得分:2)

嗯,答案几乎总是2 ^(N-10)

首先,请注意,如果您将一个元素与另一个元素进行异或,则它不会将XOR的子集数量更改为Q.

证明:假设你有一个大小为N的数组A,以及一组与特定值异或的子集。然后你做A [i] ^ = A [j],i!= j。现在,要修复所有子集以使它们与相同的值进行异或,您只需找到包含A [i]的子集,并在其中切换A [j]。因此,我们所做的XOR不会影响XOR对任何特定值的子集总数。

因此...

  1. 找到最大的元素并将其移动到位置0.然后将其与所有其他具有相同MSB(最高有效位)的元素进行异或,以便A [0]是唯一具有最大MSB的元素

  2. 找到剩余的最大元素,将其移动到位置1,并将其与具有相同MSB的所有剩余元素进行异或,因此A [1]将是唯一具有第二大MSB的元素。

  3. 尽可能多地继续使用第三大MSB等。你最终得到最多10个非零元素,所有元素都有不同的MSB,剩下的元素都是零。

  4. 让我们说你最终得到M个非零元素。如果你可以通过将这些元素混合在一起来制作Q,那么只有一种方法可以做到。其他N-M元素都为零,因此您可以在不更改总XOR值的情况下从任何子集添加或删除它们。因此,如果您可以制作Q,则会有2 ^(N-M)个子集与XOR到Q.

    如果你不能通过对那些非零元素进行异或来产生Q,那么当然XOR到Q的子集数量是0。

    有关此程序的详细信息,请参阅Google&#34;高斯消除&#34;