bzoj 2844 子集异或和名次

 

感谢:

http://blog.sina.cn/dpool/blog/s/blog_76f6777d0101d0mr.html

的讲解(特别是2^(n-m)的说明)。

 

 1 /**************************************************************
 2     Problem: 2844
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:308 ms
 7     Memory:2052 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <iostream>
12 #define Mod 10086
13 #define N 100010
14 using namespace std;
15  
16 int n, m, q;
17 int aa[N], bit[N];
18  
19 void gauss() {
20     int i=0;
21     for( int b=30; b>=0; b-- ) {
22         for( int j=i; j<n; j++ )
23             if( (aa[j]>>b)&1 ) {
24                 swap( aa[j], aa[i] );
25                 break;
26             }
27         if( (aa[i]>>b)&1 ) {
28             for( int j=i+1; j<n; j++ )
29                 if( (aa[j]>>b)&1 ) 
30                     aa[j] ^= aa[i];
31             bit[i] = b;
32             i++;
33         }
34     }
35     m = i;
36     for( int i=0; i<m; i++ )
37         for( int j=i-1; j>=0; j-- )
38             if( (aa[j]>>bit[i])&1 )
39                 aa[j] ^= aa[i];
40 }
41 int mpow( int a, int b ) {
42     int rt;
43     for( rt=1; b; b>>=1,a=(a*a)%Mod )
44         if( b&1 ) rt=(rt*a)%Mod;
45     return rt;
46 }
47 int main() {
48     scanf( "%d", &n );
49     for( int i=0; i<n; i++ )
50         scanf( "%d", aa+i );
51     scanf( "%d", &q );
52     gauss();
53     int cur = 0;
54     int rank = (q==0?0:1);
55     for( int i=0; i<m; i++ ) {
56         if( (cur^aa[i])<q ) {
57             cur ^= aa[i];
58             rank = (rank + (1<<(m-1-i))%Mod) % Mod;
59         }
60     }
61     rank = (rank*mpow(2,n-m)+1) % Mod;
62     printf( "%d\n", rank );
63 }
View Code

 

posted @ 2015-05-23 21:11  idy002  阅读(266)  评论(0编辑  收藏  举报