XOR( 异或空间
# 题意
给出$n$个数,$a_{i}$,从中选取一些进行异或运算(可以只有一个),求出他们所有可能组合得到的异或值去重后的第$k$小的值
$1 \leqslant a_{i} \leqslant 10^{18}$
# 题解
因为是去重后的值所以求出线性基然后组合即可
因为$1 \leqslant a_{i} \leqslant 10^{18}$即所有数都在二进制$64$位之间,可以将每个数看做是$64$位二进制数,通过高斯消元后求得简化的行阶梯型矩阵,
即线性基,矩阵的秩为$r$,首先最大的数即所有数异或,其余的都是组合,一共有$2^{r}$种,这里是包含了值为$0$的项,
需要判断是否存在$0$,因为题目中不会选出$a_{i} \oplus a_{i}$所以不一定存在$0$,在高斯消元后如果存在$0$,即说明存在几个数异或等于$0$
将$k-1$即可,然后通过二进制求出第$k-1$小的数,如果 $k \geqslant 2^{t}$ 即没有这么多不同的值就输出$-1$
1 #include <bits/stdc++.h> 2 #define ull long long 3 using namespace std; 4 const int N=1e4+10; 5 int n,m; 6 ull a[N]; 7 int main() { 8 int t; 9 cin >> t; 10 for (int T = 1; T <= t; T++) { 11 cin >> n; 12 for (int i = 1; i <= n; i++) 13 cin >> a[i]; 14 bool zero = 0; 15 int r = n; 16 for (int i = 1; i <= n; i++) { 17 for (int j = i + 1; j <= n; j++) 18 if (a[j] > a[i]) swap(a[i], a[j]); 19 20 if (a[i] == 0) {//最大的主元为0后面的肯定也是0 21 r = i - 1; 22 zero = 1; 23 break; 24 } 25 for (int k = 63; k >= 0; k--) 26 if (a[i] >> k & 1) { 27 for (int j = 1; j <= n; j++) 28 if (j != i && (a[j] >> k & 1)) a[j] ^= a[i]; 29 break; 30 } 31 } 32 cin >> m; 33 cout << "Case #" << T << ":" << endl; 34 while (m--) { 35 ull k, ans = 0; 36 cin >> k; 37 if (zero) k--; 38 if (k >= 1llu << r) puts("-1"); 39 else { 40 for (int i = r-1 ; i >= 0; i--) 41 if (k >> i & 1) ans ^= a[r - i]; 42 cout << ans << endl; 43 } 44 } 45 } 46 }