题意:有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 }
posted on 2012-09-03 21:42  DrunBee  阅读(1403)  评论(0编辑  收藏  举报