bzoj4036 / P3175 [HAOI2015]ビットごとのOR
あるmin-max容斥
ボードの問題が。
min-max容斥
式:
$ \ displaystyle MAX(S)= \ sum_ {T \ sube S}(-1)^ {| T | 1}分(T)$
そして非常に良い、それは望ましくない状況に設立されました!
これは、それに関係しています。。
各別々に考えた場合は最初の$ I $の1のビットが所望の時間になった場合、$ $ T(i)は
その後、シークは、$ E(MAX(T_ {1つの\ドットのn}))$です
これは、することができ min-max容斥
$分$を探して、1つになることができたのサブセットである1
所望の回数。
1は、このサブセットになることができます選択肢を検討1
する確率を、すべてのビットのこのサブセットの1--確率は0と数字ですが、$ S $を作るに加えて考えることができるビットのサブセットは、他のゼロすべてです1の数(セット)は、確率が$ 1である- \ sum_は{[ I] \ sube S} P_I $は、 各選択に相当し、それは望ましいこと$ \ FRAC {1} {P } $
そして、MINMAX含める排除式の種類$ | T | $ $ S $は、実際にはゼロの数ですn - popcount
この計算は、実際には半分または畳み込みであります
複雑$(N2 ^ n)のO $
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
#define MAXN ( 1 << 21 ) + 6
int n;
double p[MAXN];
inline void FWT(double a[], int len) {
for (int mid = 2; mid <= len; mid <<= 1)
for (int i = 0; i < len; i += mid)
for (int j = i; j < i + (mid >> 1); j++)
a[j + (mid >> 1)] += a[j];
}
int main() {
cin >> n;
for( int i = 0 ; i < ( 1 << n ) ; ++ i ) scanf("%lf",&p[i]);
FWT( p , ( 1 << n ) );
double ans = 0.0;
for( int i = 0 ; i < ( 1 << n ) - 1; ++ i ) {
ans += ( ( n - __builtin_popcount( i ) & 1 ) ? 1.0 : -1.0 ) / ( 1.0 - p[i] );
}
if( ans > 1e50 ) puts("INF");
else printf("%.7lf",ans);
}