【问题标题】:Finding the No. of Subset with a Given Xor使用给定的 Xor 查找子集的编号
【发布时间】:2016-03-12 06:07:58
【问题描述】:

我有一个包含 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)。 这可能吗,频率数组有用吗?

【问题讨论】:

  • 子集是否必须有一定的大小?它们是由数组中的相邻元素组成的吗?
  • 所以你有F,它是一个介于 0 到 1,023 之间的随机数数组。您有Q,它是同一范围内的随机数。您想知道插入F[x]^F[y] 的x、y 组合有多少可以等于Q?例如:如果F = [0,1,1,2,2,2,3,3,3,3]Q = 3 那么ways 应该是10? (1*4 + 2*3)
  • @m69 子集可以是任意大小 2^n 子集是可能的
  • 频率阵列会有所帮助,但这只是第一步。如果你发现一个集合 [x,y,z] 异或到 q,那么 [x,y,z,z,z] 和 [x,y,z,k,k] 和 [x,y,z ,k,k,k,k] 也是有效答案。但这仍然留下了在 2^1024 个可能的集合中找到 [x,y,z] 的任务,这是一个不切实际的大数字。要么有一个数学技巧来简化这个问题,要么你误解了这个问题。

标签: algorithm data-structures xor


【解决方案1】:

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

首先,请注意,如果您将一个元素异或到另一个元素,它不会改变异或到 Q 的子集的数量。

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

所以...

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

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

  3. 继续使用第三大 MSB 等,尽可能多地进行。您最终最多有 10 个非零元素,所有元素都具有不同的 MSB,其余元素都将为零。

假设你最终得到了 M 个非零元素。如果您可以通过对这些元素进行异或运算来生成 Q,那么只有一种方法可以做到。其他 N-M 个元素都为零,因此您可以在任何子集中添加或删除它们,而无需更改总异或值。因此,如果您可以制作 Q,那么将有 2^(N-M) 个子集与 Q 进行异或。

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

有关此过程的更多信息,请谷歌“高斯消元法”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2021-10-15
    • 2022-01-24
    • 2021-03-01
    相关资源
    最近更新 更多