本题题意是给你两个罐子,每个里面都有n个糖,现在LazyChild每天要随机从一个里面拿出一个糖,且选择其中一个罐子的概率为p,问当他某天打开罐子时发现里面没有糖了,问另外一个罐子中糖果数的期望。
期望公式很好得出
很明显,200000太大了,不能直接排列组合。
然后需要一个快速排列组合函数:logC(m,n)
有了上面的算式之后,C(m,n)=exp(logC(m,n))f[0]=0; for(int i=1;i<=400002;i++) f[i]=f[i-1]+log(i*1.0);
double logC(int m,int n){ return f[m]-f[n]-f[m-n]; }
所以算式变为
#include<cstdio>
#include<cmath>
double f[400005];
double logC(int m,int n){ //logC(m,n) = f[m]-f[n]-f[m-n]; 正不正确自己代入数验证。
return f[m]-f[n]-f[m-n];
}
int main(){
f[0]=0;
for(int i=1;i<=400002;i++) f[i]=f[i-1]+log(i*1.0); //为了算C(m,n)做得预处理
int apple=1,n;
double p,q;
while(~scanf("%d",&n)){
scanf("%lf",&p);
q=1-p;
double p1 = log(p), p2 = log(q);
double ans=0;
for(int k=0;k<=n;k++){
ans+=(n-k)*( exp(logC(n+k,k)+(n+1)*p1+k*p2) + exp(logC(n+k,k)+(n+1)*p2+k*p1));
}
printf("Case %d: %.6f\n",apple++,ans);
}
return 0;
}