异或线性基

问题

给定一个数组 \(A = [a_1, a_2,...a_n]\) ,其中 \(a_i ≤ 2d\) ,在 A 中选择元素的某个子集,并将它们 XOR。求你能得到的不同元素的个数。

思路

显然可以得到一个效率非常劣的做法

x[0].insert(0);
for (int i = 1; i <= n; i++) {
  x[i] = x[i - 1];
  for (auto cur : x[i - 1]) {
    x[i].insert(cur ^ a[i - 1]);
  }
}
cout << x[n].size();

我们可以研究一下集合的性质,我们假设 \(a, b\) 为集合中的两个元素,那么 \(a \oplus b\) 也必然在集合中,现在我们回头来考虑一下 \(x_i\)\(a_{i + 1}\) 计算 \(x_{i + 1}\) 的过程 \(:\) 如果 \(a_{i + 1} \in x_i\)那么不用考虑 \(a_{i + 1}\) 的影响,如果没有,那么集合大小铁定会翻两倍,那么这个集合最多大小翻 \(d\) 倍,由此我们可以得到一个时间复杂度为 \(O(n + 2^d)\) 的代码
如果 \(2^d\) 很大,这种算法也会超时

posted @ 2024-09-23 15:25  libohan0518  阅读(3)  评论(0编辑  收藏  举报