我有一个包含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,我可以维持频率F [i]的数组,将上述代码减少到O(1024 * 1024).
这可能,频率阵列可能有用吗?
最佳答案 好吧,答案几乎总是2 ^(N-10)
首先,请注意,如果将一个元素与另一个元素进行异或,则不会将XOR的子集数更改为Q.
证明:假设你有一个大小为N的数组A,以及一组与特定值异或的子集.然后你做A [i] ^ = A [j],i!= j.现在,要修复所有子集以使它们与相同的值进行异或,您只需找到包含A [i]的子集,并在其中切换A [j].因此,我们所做的XOR不会影响XOR对任何特定值的子集总数.
所以…
>找到最大的元素并将其移动到位置0.然后将其XOR到具有相同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.
有关此过程的更多信息,谷歌“高斯消除”