码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4036 / P3175 [HAOI2015]按位或

时间:2019-12-28 12:52:44      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:can   计算   情况   集合   spl   等价   sub   mes   class   

bzoj4036 / P3175 [HAOI2015]按位或

是一个 min-max容斥 的板子题。

min-max容斥 式子:

$ \displaystyle max(S) = \sum_{T\sube S} (-1)^{|T|+1} min(T) $

并且很优秀的是,它在期望情况下成立!

这个有什么关系呢。。

如果每一位分开考虑,如果第 $ i $ 位变成 1 的期望时间是 $ T(i) $

那么求的是 $ E(max(T_{1\dots n})) $

这个可以 min-max容斥

求 $ min $ 的就是某一个子集让其中某一个变成 1 的期望次数。

考虑一次选择可以让这个子集的某一个变成 1 的概率,就是 1 - 这个子集所有位都是 0 的数字的概率的和,可以考虑令 $ S $ 是除了子集的位是0其他都是1的数(集合),概率就是 $ 1 - \sum_{A[i] \sube S} p_i $ 每次选择是等价的,所以期望就是 $ \frac{1}{p} $

然后minmax容斥式子种 $ |T| $ 其实就是 $ S $ 中 0 的个数,就是n - popcount

这个的计算其实就是半个 或卷积

复杂度 $ O(n2^n) $

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

bzoj4036 / P3175 [HAOI2015]按位或

标签:can   计算   情况   集合   spl   等价   sub   mes   class   

原文地址:https://www.cnblogs.com/yijan/p/bzoj4036.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!