传送门
考虑
f
i
,
j
f_{i,j}
fi,j表示第
i
i
i秒选择的数并起来结果为
j
j
j的方案。
那么
a
n
s
s
=
∑
T
=
0
+
∞
T
(
f
T
,
s
−
f
T
−
1
,
s
)
=
lim
T
→
+
∞
T
f
T
,
s
−
∑
T
=
0
+
∞
f
T
,
s
\begin{aligned}ans_s=&\sum\limits_{T=0}^{+\infin}T(f_{T,s}-f_{T-1,s})\\=&\lim\limits_{T\rightarrow+\infin}Tf_{T,s}-\sum\limits_{T=0}^{+\infin}f_{T,s}\end{aligned}
anss==T=0∑+∞T(fT,s−fT−1,s)T→+∞limTfT,s−T=0∑+∞fT,s
然后用
f
m
t
fmt
fmt转化一下然后做个等比数列求和即可。
注意
p
i
p_i
pi等于
1
1
1的时候要特判。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=1<<20|5;
double a[N];
int n,len;
inline void fmt(double*a,int type){
for(ri i=0,t=1;i<n;++i,t<<=1)for(ri j=0,l=t<<1;j<len;j+=l)
for(ri k=0;k<t;++k)a[(j+k)^t]+=a[j+k]*type;
}
const double eps=1e-6;
inline int sgn(double x){return (x>eps)-(x<-eps);}
int main(){
#ifdef ldxcaicai
freopen("lx.in","r",stdin);
#endif
scanf("%d",&n),len=1<<n;
for(ri i=0;i<len;++i)scanf("%lf",&a[i]);
fmt(a,1);
for(ri i=0;i<len;++i)a[i]=sgn(a[i]-1)?-1.0/(1.0-a[i]):0;
fmt(a,-1);
if(a[len-1]<eps)puts("INF");
else printf("%.10lf",a[len-1]);
return 0;
}