bzoj4036 / P3175 [HAOI2015]ビットごとのOR

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);
}

おすすめ

転載: www.cnblogs.com/yijan/p/bzoj4036.html