Description
判断一个异或值是第几小。
Solution
允许有空集存在,则能够异或出的 \(0\) 的个数为 \(2^{n-cnt}\),其中 \(n\) 为插入的数字个数,\(cnt\) 为线性基中的元素个数。
二进制拆分,每个不同的异或值都会出现 \(2^{n-cnt}\) 次,输出时乘上即可。
Code
#include <cstdio>
#include <cstring>
const int mod = 10086;
int T, n, x, cnt = -1, ans, zero, id[35], p[35];
void insert(int x) {
for (int i = 30; ~i; --i) {
if (!(x >> i)) continue;
if (!p[i]) { p[i] = x; break; }
x ^= p[i];
}
}
void rebuild() {
for (int i = 30; ~i; --i)
for (int j = i - 1; ~j; --j)
if (p[i] & (1 << j)) p[i] ^= p[j];
for (int i = 0; i <= 30; ++i)
if (p[i]) id[i] = ++cnt;
}
int pow(int a, int b) {
int res = 1;
for (; b; b >>= 1, a = a * a % mod)
if (b & 1) res = res * a % mod;
return res;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &x), insert(x);
rebuild();
scanf("%d", &x), zero = pow(2, n - cnt - 1);
for (int i = 0; i <= 30; ++i)
if (((x >> i) & 1) && p[i]) ans = (ans + (1 << id[i])) % mod;
printf("%d\n", (ans * zero + 1) % mod);
return 0;
}