我有一个包含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)。
这可能吗,频率数组可能有用吗?
答案 0 :(得分:2)
嗯,答案几乎总是2 ^(N-10)
首先,请注意,如果您将一个元素与另一个元素进行异或,则它不会将XOR的子集数量更改为Q.
证明:假设你有一个大小为N的数组A,以及一组与特定值异或的子集。然后你做A [i] ^ = A [j],i!= j。现在,要修复所有子集以使它们与相同的值进行异或,您只需找到包含A [i]的子集,并在其中切换A [j]。因此,我们所做的XOR不会影响XOR对任何特定值的子集总数。
因此...
找到最大的元素并将其移动到位置0.然后将其与所有其他具有相同MSB(最高有效位)的元素进行异或,以便A [0]是唯一具有最大MSB的元素
找到剩余的最大元素,将其移动到位置1,并将其与具有相同MSB的所有剩余元素进行异或,因此A [1]将是唯一具有第二大MSB的元素。
尽可能多地继续使用第三大MSB等。你最终得到最多10个非零元素,所有元素都有不同的MSB,剩下的元素都是零。
让我们说你最终得到M个非零元素。如果你可以通过将这些元素混合在一起来制作Q,那么只有一种方法可以做到。其他N-M元素都为零,因此您可以在不更改总XOR值的情况下从任何子集添加或删除它们。因此,如果您可以制作Q,则会有2 ^(N-M)个子集与XOR到Q.
如果你不能通过对那些非零元素进行异或来产生Q,那么当然XOR到Q的子集数量是0。
有关此程序的详细信息,请参阅Google&#34;高斯消除&#34;