一、题目
二、解法
设
m
a
x
(
S
)
max(S)
max(S)表示组成
S
S
S的最后一个元素的出现时间,
m
i
n
(
S
)
min(S)
min(S)表示组成
S
S
S的第一个元素的出现时间,这个是用时间顺序作为大小关系的,所以可以套用
min-max
\text{min-max}
min-max容斥,下文的
E
E
E表示期望,
U
U
U表示全集,我们要求的是
E
(
m
a
x
(
U
)
)
E(max(U))
E(max(U)):
E
(
m
a
x
(
U
)
)
=
∑
S
≠
∅
(
−
1
)
∣
s
∣
−
1
E
(
m
i
n
(
S
)
)
E(max(U))=\sum_{S\not=\empty}(-1)^{|s|-1}E(min(S))
E(max(U))=S=∅∑(−1)∣s∣−1E(min(S))关键在于如果快速求
E
(
m
i
n
(
S
)
)
E(min(S))
E(min(S))了,设
p
(
m
i
n
(
S
)
=
i
)
p(min(S)=i)
p(min(S)=i)表示这个出现时间为
i
i
i的概率,那么:
E
(
m
i
n
(
S
)
)
=
∑
i
=
1
+
∞
i
×
p
(
m
i
n
(
S
)
=
i
)
E(min(S))=\sum_{i=1}^{+\infty}i\times p(min(S)=i)
E(min(S))=i=1∑+∞i×p(min(S)=i)现在考虑如何计算
p
(
m
i
n
(
S
)
=
i
)
p(min(S)=i)
p(min(S)=i),我们前
i
−
1
i-1
i−1个时间选不到,正好在
i
i
i时间选到:
p
(
m
i
n
(
S
)
=
i
)
=
(
∑
T
∩
S
=
∅
a
[
T
]
)
i
−
1
(
1
−
∑
T
∩
S
=
∅
a
[
T
]
)
p(min(S)=i)=(\sum_{T\cap S=\empty}a[T])^{i-1}(1-\sum_{T\cap S=\empty}a[T])
p(min(S)=i)=(T∩S=∅∑a[T])i−1(1−T∩S=∅∑a[T])方便推导,我们设
x
=
∑
T
∩
S
=
∅
a
[
T
]
x=\sum_{T\cap S=\empty}a[T]
x=∑T∩S=∅a[T],把上面的式子带到
E
(
m
i
n
(
S
)
)
E(min(S))
E(min(S))中去,可以发现:
E
(
m
i
n
(
S
)
)
=
∑
i
=
1
+
∞
i
(
x
)
i
−
1
(
1
−
x
)
=
∑
i
=
1
∞
i
x
i
−
1
−
i
x
i
E(min(S))=\sum_{i=1}^{+\infty}i(x)^{i-1}(1-x)=\sum_{i=1}^{\infty}ix^{i-1}-i x^{i}
E(min(S))=i=1∑+∞i(x)i−1(1−x)=i=1∑∞ixi−1−ixi仔细观察一下,就会化成这个形式:
E
(
m
i
n
(
S
)
)
=
∑
i
=
0
∞
x
i
=
1
1
−
x
=
1
1
−
∑
T
∩
S
=
∅
a
[
T
]
E(min(S))=\sum_{i=0}^{\infty}x^i=\frac{1}{1-x}=\frac{1}{1-\sum_{T\cap S=\empty}a[T]}
E(min(S))=i=0∑∞xi=1−x1=1−∑T∩S=∅a[T]1其实吧,
∑
T
∩
S
=
∅
a
[
T
]
=
∑
T
⊆
C
U
S
a
[
T
]
\sum_{T\cap S=\empty}a[T]=\sum_{T\subseteq C_US}a[T]
∑T∩S=∅a[T]=∑T⊆CUSa[T],这显然就是
o
r
or
or卷积可以求出来的东西,套板子预处理,然后用第一个式子算就行了,时间复杂度
O
(
n
2
n
)
O(n2^n)
O(n2n)
#include <cstdio>
#define db double
const int M = 1<<20;
int read()
{
int num=0,flag=1;char c;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();
return num*flag;
}
int n,m,bit[M];db ans,a[M];
void fwt(db *a,int n,int op)
{
for(int i=1;i<n;i<<=1)
for(int p=i<<1,j=0;j<n;j+=p)
for(int k=0;k<i;k++)
{
if(op==1) a[i+j+k]=a[i+j+k]+a[j+k];
else a[i+j+k]=a[i+j+k]-a[j+k];
}
}
int main()
{
n=read();m=1<<n;
for(int i=0;i<m;i++)
{
scanf("%lf",&a[i]);
bit[i]=bit[i>>1]+(i&1);
}
fwt(a,m,1);
for(int i=1;i<m;i++)
{
int Cu=i^(m-1);
if(1-a[Cu]<1e-8)
{
puts("INF");
return 0;
}
db v=1.0/(1.0-a[Cu]);
ans+=(bit[i]%2?1:-1)*v;
}
printf("%.10lf\n",ans);
}