bzoj 4036 集合幂级数

 

集合幂级数其实就是一种集合到数的映射,并且我们针对集合的一些操作(or  xor and specil or )为这种映射定义运算.其中一些东西可以通过某些手段将其复杂度降低.

 

orz vfk

 

 1 /**************************************************************
 2     Problem: 4036
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:3584 ms
 7     Memory:13092 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cmath>
12 #define eps 1e-10
13 #define N 20
14  
15 int n, bound;
16 long double f[1<<N];
17  
18 int sg( long double x ) { return (x>-eps)-(x<eps); }
19  
20 void trans() {
21     for( int i=0; i<n; i++ ) {
22         int ss=bound^(1<<i);
23         f[ss|(1<<i)] += f[ss];
24         for( int s=(ss-1)&ss; s!=ss; s=(s-1)&ss ) 
25             f[s|(1<<i)] += f[s];
26     }
27 }
28 void inverse() {
29     for( int i=0; i<n; i++ ) {
30         int ss=bound^(1<<i);
31         f[ss|(1<<i)] -= f[ss];
32         for( int s=(ss-1)&ss; s!=ss; s=(s-1)&ss ) 
33             f[s|(1<<i)] -= f[s];
34     }
35 }
36  
37 int main() {
38     scanf( "%d", &n );
39     bound = (1<<n)-1;
40     for( int s=0; s<=bound; s++ ) 
41         scanf( "%Lf", f+s );
42     trans();
43     for( int s=0; s<=bound; s++ ) {
44         if( sg(f[s]-1)==0 ) 
45             f[s] = 0;
46         else
47             f[s] = 1/(f[s]-1);
48     }
49     inverse();
50     if( sg(f[bound])==0 ) 
51         printf( "INF\n" );
52     else
53         printf( "%.10Lf\n", f[bound] );
54 }
View Code

 


感谢Picks:http://picks.logdown.com/posts/179290-fast-walsh-hadamard-transform

现在可以做or, and, xor, 以及它们的否的卷积了。

 

 1 #include <cstdio>
 2 
 3 const int N = 10;
 4 
 5 int n, U;
 6 int a[1<<N], b[1<<N], c[1<<N];
 7 
 8 void trans( int a[], int flag ) {
 9     for( int b=0; b<n; b++ ) {
10         int u = U ^ (1<<b);
11         for( int s=u,t=1<<(n-1); t; s=(s-1)&u,t-- ) {
12             int l=a[s], r=a[s|(1<<b)];
13             /*
14             NOT AND
15             if( flag==1 ) {
16                 a[s] = l+r;
17                 a[s|(1<<b)] = r;
18             } else {
19                 a[s] = r;
20                 a[s|(1<<b)] = l-r;
21             }
22              */
23             /*
24             NOT XOR
25             if( flag==1 ) {
26                 a[s] = l+r;
27                 a[s|(1<<b)] = l-r;
28             } else {
29                 a[s] = (l-r)/2;
30                 a[s|(1<<b)] = (l+r)/2;
31             }
32              */
33             /*
34             NOT OR
35             if( flag==1 ) {
36                 a[s] = l;
37                 a[s|(1<<b)] = l+r;
38             } else {
39                 a[s] = r-l;
40                 a[s|(1<<b)] = l;
41             }
42             */
43             /*
44             OR
45             if( flag==1 ) {
46                 a[s] = l;
47                 a[s|(1<<b)] = l+r;
48             } else {
49                 a[s] = l;
50                 a[s|(1<<b)] = r-l;
51             }
52             */
53             /*
54             AND
55             if( flag==1 ) {
56                 a[s] = l+r;
57                 a[s|(1<<b)] = r;
58             } else {
59                 a[s] = l-r;
60                 a[s|(1<<b)] = r;
61             }
62             */
63             /*
64             XOR
65             if( flag==1 ) {
66                 a[s] = l+r;
67                 a[s|(1<<b)] = l-r;
68             } else {
69                 a[s] = (l+r)/2;
70                 a[s|(1<<b)] = (l-r)/2;
71             }
72             */
73         }
74     }
75 }
76 int main() {
77     scanf( "%d", &n );
78     U = (1<<n)-1;
79     for( int i=0; i<=U; i++ )
80         scanf( "%d", a+i );
81     for( int i=0; i<=U; i++ )
82         scanf( "%d", b+i );
83     trans(a,1);
84     trans(b,1);
85     for( int s=0; s<=U; s++ )
86         c[s] = a[s]*b[s];
87     trans(c,-1);
88     for( int s=0; s<=U; s++ )
89         printf( "%d ", c[s] );
90     printf( "\n" );
91 }
View Code

 

posted @ 2015-06-09 23:19  idy002  阅读(405)  评论(0编辑  收藏  举报