题意:有n个数,至少取一个异或可以得到一些值,询问这些值中第k小是多少。
用高斯消元搞基。
将n个数拆成二进制,转化为非线性相关。
因此,这n个数都要尽可能小,且不能相互表示。
不能相互表示,用高斯消元。尽可能小,则要从高位开始消去。
1 #include<cstdio> 2 #include<algorithm> 3 #define MAXN 10010 4 typedef long long LL; 5 using namespace std; 6 int n; 7 LL a[MAXN]; 8 void Gauss() { 9 int i, j, k, t; 10 k = 0; 11 for (i = 60; i >= 0; i--) { 12 for (j = k; j < n; j++) { 13 if ((a[j] >> i) & 1) 14 break; 15 } 16 if (j < n) { 17 swap(a[j], a[k]); 18 for (t = 0; t < n; t++) { 19 if (t != k && ((a[t] >> i) & 1)) 20 a[t] ^= a[k]; 21 } 22 k++; 23 } 24 } 25 sort(a, a + n); 26 n = unique(a, a + n) - a; 27 } 28 LL Cal(int k) { 29 LL ans; 30 int i; 31 ans = i = 0; 32 if (a[0] == 0) { 33 if (k == 1) 34 return 0; 35 k--; 36 i++; 37 } 38 for (; i < n && k; k >>= 1, i++) { 39 if (k & 1) 40 ans ^= a[i]; 41 } 42 if (i == n && k) 43 return -1; 44 return ans; 45 } 46 int main() { 47 int c, ca = 1; 48 int i, q; 49 LL k; 50 scanf("%d", &c); 51 while (c--) { 52 scanf("%d", &n); 53 for (i = 0; i < n; i++) 54 scanf("%I64d", &a[i]); 55 Gauss(); 56 scanf("%d", &q); 57 printf("Case #%d:\n", ca++); 58 while (q--) { 59 scanf("%I64d", &k); 60 printf("%I64d\n", Cal(k)); 61 } 62 } 63 return 0; 64 }