如果每个位置上的数字的意义是这个位置被加进集合的最早时间,那么我们要求的就是集合中最大数的期望,使用Min-Max容斥,(E(max(S))=sum_{Tsubset S}(-1)^{|T|+1}E(min(T))),这里的(E(min(T)))是集合中加进数字的期望时间,根据题意,加进一个集合数字概率为(sum_{scap T eemptyset}P_s),对应的期望,也就是(E(min(T))=frac{1}{sum_{scap T eemptyset}P_s})
但是(sum_{scap T eemptyset}P_s)不是很好求,可以转化成(1-sum_{scap T=emptyset}P_s),也就是(1-sum_{ssubset ∁_{S}T}P_s),高维前缀和即可
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
using namespace std;
const int N=(1<<20)+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,nn;
db p[N],ans,h[N];
int main()
{
n=rd();
nn=(1<<n)-1;
int ff=0;
for(int i=0;i<=nn;++i)
{
scanf("%lf",&p[i]);
if(p[i]>1e-8) ff|=i;
}
if(ff^nn) return puts("INF"),0;
for(int i=1;i<=nn;i<<=1)
for(int j=0;j<=nn;++j)
if((j&i)==i) p[j]+=p[j^i];
h[0]=1;
for(int i=0;i<=nn;++i)
{
h[i]=-h[i^(i&(-i))];
if(fabs(1-p[nn^i])>1e-8)ans+=h[i]*1/(1-p[nn^i]);
}
printf("%.8lf
",ans);
return 0;
}