Description:
刚开始你有一个数字
0
,每一秒钟你会随机选择一个
Solution:
如果令
Fi(x)
表示在进行完
i
次操作之后,手上的数为
其中
令 Gi(x)=∑xj|x=xFi(j) ,那么
观察
Gi(x)
的定义式
Gi(x)=∑xj|x=xFi(j)
,令函数
C(x)
表示
x
的二进制表示中有多少个
所以:
求和可得:
怎么判断无解,只用看看最后算出来的Ans是不是收敛的,如果是的,就是有解,否则输出
INF
Code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int N;
double P[2000010]={0};
int N2;
double S[2000010]={0};
int Num[2000010]={0};
int main()
{
cin>>N;
N2=1<<N;
for(int i=0;i<N2;i++)
{
scanf("%lf",&P[i]);
S[i]=P[i];
}
for(int i=0;i<N;i++)
{
for(int j=0;j<N2;j++)
if(j&(1<<i))
{
S[j]+=S[j^(1<<i)];
Num[j]++;
}
}
for(int i=0;i<N2-1;i++)
if(S[i]>=1-1e-8)
{
cout<<"INF"<<endl;
return 0;
}
double Ans=0;
for(int i=0;i<N2-1;i++)
{
if((N-Num[i])&1)
Ans-=1/(S[i]-1);
else Ans+=1/(S[i]-1);
}
printf("%.10lf\n",Ans);
return 0;
}