题目
https://www.luogu.com.cn/problem/P3175
刚开始你有一个数字 0 0 0,每次给这个数按一定概率 o r or or上一个 ≤ 2 n − 1 ≤2^n−1 ≤2n−1的非负整数,第 i i i个数的概率为 p i p_i pi,保证和为 1 1 1问,这个数字到 2 n − 1 2^n−1 2n−1的期望 o r or or次数。 n ≤ 20 n≤20 n≤20
思路
把数字看成集合,用
m
i
n
−
m
a
x
min-max
min−max反演
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))=T⊆S∑(−1)∣T∣−1E(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=Q∩T=∅∑pQ=Q⊆∁UT∑pQ
这是一个子集和的形式,用
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(1−PT)(i+1)=1−PT1
E
(
m
i
n
(
T
=
∅
)
)
=
0
E(min(T=\empty))=0
E(min(T=∅))=0不用考虑,如果
1
−
P
T
=
0
1-P_T=0
1−PT=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;
}