【数学】CF251D. Two Sets

http://codeforces.com/contest/251/problem/D

     很有意思的一个数学题,给你n个数字要你将其分成A,B两组,使得两组所有数字分别xor起来,得到A‘,B’时,A+B最大。多解时候使得A最小。

     先贴程序。。。。吃饭先

View Code
 1 //By Lin
 2 #include<cstdio>
 3 #include<cstring>
 4 #define maxn 100050
 5 using namespace std;
 6 typedef long long LL;
 7 int        n;
 8 LL        data[maxn],input[maxn];
 9 int        mark[maxn],w[64];
10 int        num[64],ans[64],que[64];
11 bool    mat[maxn][64];
12 
13 void writ(LL x){
14     printf(" ");
15     for (int i = 9; i>=0; i-- ) if ( (x&(1ll<<i)) ) printf("1"); else printf("0");
16 }
17 LL    com(LL x ,int k ) {
18     return (-1ll^((1ll<<k)-1))&x;
19     return x;
20 }
21 int        main(){
22     scanf("%d", &n );
23     for (int i = 0; i<n; i++) {
24         scanf("%I64d", &data[i] );
25         input[i] = data[i];
26         for (int l = 0; l<64; l++) if ( data[i]&(1ll<<l) ) num[l] ^= 1;
27     }
28     int cnt = 0;
29     for (int l = 63; l>=0; l--) if (!num[l] ) que[cnt++] = l;
30     for (int l = 63; l>=0; l--) if ( num[l] ) que[cnt++] = l;
31     LL    now = 0;
32     for (int k = 0; k<cnt; k++){
33         int l = que[k];
34         for (int i = 0; i<n; i++) if ( !mark[i] && (data[i]&(1ll<<l)) ){
35             mark[i] = true;
36             w[l] = i; 
37             for (int j = 0; j<n; j++) if ( !mark[j] && ( data[j]&(1ll<<l) ) ){
38                 data[j] ^= data[i];
39                 mat[j][l] = 1;
40             }
41             if ( now&(1ll<<l) ) continue;
42             now ^= data[i];
43             ans[l]++;
44             break;
45         }
46     }
47     memset( mark , 0 , sizeof(mark) );
48     for (int k = cnt-1; k>=0; k--){
49         int l = que[k];
50         if ( w[l]==-1 || ans[l]%2==0 ) continue;
51         mark[w[l]] = 1;
52         for (int j = 0; j<64; j++) 
53             if ( mat[w[l]][j] ) ans[j]++;
54     }
55     LL    a ,b;
56     a = b = 0;
57     for (int i = 0; i<n; i++) {
58         printf("%d%c", mark[i]?2:1 , i==n-1?'\n':' ' );
59         if ( mark[i] ) a^=input[i];
60         else b^=input[i];
61     }
62     return 0;
63 }

 

posted @ 2012-12-10 17:28  lzqxh  阅读(330)  评论(0编辑  收藏  举报