题目:
https://ac.nowcoder.com/acm/problem/16604
有 n n n枚硬币,正面朝上为 1 1 1,反面为 0 0 0,第 i i i枚硬币朝上的概率为 p i pi pi。随机抛每枚硬币,把数字异或起来得到 S U M SUM SUM。问有多少种硬币集合使得 S U M = 1 SUM=1 SUM=1的概率等于 S U M = 0 SUM=0 SUM=0的概率。
思路:
假设集合
A
A
A的
S
U
M
=
1
SUM=1
SUM=1得概率为
P
(
1
)
P(1)
P(1),同理
P
(
0
)
P(0)
P(0)。
这时把硬币
i
i
i考虑进去得到新的集合
B
B
B,概率为
P
′
P^{'}
P′,则有
P
′
(
0
)
=
(
1
−
p
i
)
P
(
0
)
+
p
i
P
(
1
)
P
′
(
1
)
=
p
i
P
(
0
)
+
(
1
−
p
i
)
P
(
1
)
\begin{aligned} P^{'}(0)&=(1-p_i)P(0)+p_iP(1)\\ P^{'}(1)&=p_iP(0)+(1-p_i)P(1)\\ \end{aligned}
P′(0)P′(1)=(1−pi)P(0)+piP(1)=piP(0)+(1−pi)P(1)
若
P
′
(
0
)
=
P
′
(
1
)
P^{'}(0)=P^{'}(1)
P′(0)=P′(1),则有
(
1
−
2
p
i
)
P
(
0
)
=
(
1
−
2
p
i
)
P
(
1
)
(1-2p_i)P(0)=(1-2p_i)P(1)\\
(1−2pi)P(0)=(1−2pi)P(1)
则
p
i
=
1
2
p_i=\frac{1}{2}
pi=21或
P
(
0
)
=
P
(
1
)
P(0)=P(1)
P(0)=P(1),显然如果一个集合满足题目要求,则该集合一定包含硬币
i
(
p
i
=
1
2
)
i(p_i=\frac{1}{2})
i(pi=21)。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int T;
ll ksm(ll a,int b)
{
ll res=1;
while(b)
{
if(b%2)
res*=a;
a*=a;
b/=2;
}
return res;
}
int main()
{
cin>>T;
while(T--)
{
getchar();
int n,num=0;
cin>>n;
for(int i=1;i<=n;i++)
{
double x;
cin>>x;
num+=(x!=0.5?1:0);
}
cout<<ksm(2,n)-ksm(2,num)<<endl;
}
return 0;
}