【HDU】3949 XOR

题意:有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 }

你可能感兴趣的:(HDU)