按位或

题目
https://www.luogu.com.cn/problem/P3175

刚开始你有一个数字 0 0 0,每次给这个数按一定概率 o r or or上一个 ≤ 2 n − 1 ≤2^n−1 2n1的非负整数,第 i i i个数的概率为 p i p_i pi,保证和为 1 1 1问,这个数字到 2 n − 1 2^n−1 2n1的期望 o r or or次数。 n ≤ 20 n≤20 n20

思路
把数字看成集合,用 m i n − m a x min-max minmax反演
E ( m a x ( S ) ) = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 E ( m i n ( T ) ) E(max(S))=\sum_{T\subseteq S}(-1)^{|T|-1}E(min(T)) E(max(S))=TS(1)T1E(min(T))
每次选取的集合不和 T T T有交集的概率为 P T P_T PT
P T = ∑ Q ∩ T = ∅ p Q = ∑ Q ⊆ ∁ U T p Q \begin{aligned} P_T&=\sum_{Q\cap T=\emptyset}p_Q\\ &=\sum_{Q\subseteq \complement_UT}p_Q \end{aligned} PT=QT=pQ=QUTpQ
这是一个子集和的形式,用 F M T FMT FMT
E ( m i n ( T ) ) = ∑ i = 0 + ∞ P T i ( 1 − P T ) ( i + 1 ) = 1 1 − P T \begin{aligned} E(min(T))&=\sum_{i=0}^{+\infty}P_T^i(1-P_T)(i+1)\\ &=\frac{1}{1-P_T} \end{aligned} E(min(T))=i=0+PTi(1PT)(i+1)=1PT1
E ( m i n ( T = ∅ ) ) = 0 E(min(T=\empty))=0 E(min(T=))=0不用考虑,如果 1 − P T = 0 1-P_T=0 1PT=0,则说明无解。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=22;
const double eps=1e-7;
int n,tot;
double a[1<<N],ans=0;
int ct(int x){
    return __builtin_popcount(x);
}
void FMT(double *a,int n,int flag) {
    for(int i=0; i<n; i++)
        for(int j=0; j<(1<<n); j++)
            if(j>>i&1)
                a[j]=a[j]+flag*a[j^(1<<i)];
}

int main() {
    scanf("%d",&n);
    tot=1<<n;
    for(int i=0; i<tot; i++)
        scanf("%lf",&a[i]);
    FMT(a,n,1);
    for(int i=1;i<tot;i++){//空集不用管
        if(1-a[(tot-1)^i]<eps){
            printf("INF");
            return 0;
        }
        ans+=1.0/(1-a[(tot-1)^i])*(ct(i)&1?1:-1);
    }
    printf("%.8f",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值