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 }
感谢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 }