题意
有m家巧克力店,要去其中的n家,从中买k个巧克力。每家店最多只能买一个巧克力。进某家店的概率为p,进了店就一定会买巧克力。问在第n家店(最后一家店)买第k块(最后一块)巧克力的概率是多少。答案对1000000007
取模。
思路
可以很容易的得到答案是$C_{n}^kp^k(1-p)^{n-k}$ 。看到p是一个三位小数,因此给p乘1000便得到了整数。进每家店的概率便成了$\frac{p}{1000}$ 。所以就是直接求原式对1000000007
取模。其中分母的部分都求逆元即可。这里因为模数是个质数,所以直接用费马小定理就可以求逆元了。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <iostream>
#include <map>
#include <set>
//#define test
using namespace std;
const int Nmax=1e6+7;
typedef unsigned long long ll;
const ll mod = 1000000007LLu;
ll n,m,k,ans,p;
double p0;
ll qmod(ll base,ll t)
{
ll ans=1LLu;
base=base%mod;
while(t)
{
if(t&1LLu)
ans=(ans*base)%mod;
base=(base*base)%mod;
t>>=1;
}
while(ans<0)
ans+=mod;
return ans;
}
int main()
{
#ifdef test
#endif
scanf("%llu%llu%llu%lf",&m,&n,&k,&p0);
if(n>m)
return 0*printf("0\n");
if(k>n)
return 0*printf("0\n");
//p=(1LLu)*1000*p0;
p=(1LLu)*floor(p0*1000.0+1e-10);
//printf("p:%llu\n",p);
ll inv=qmod(1000LLu,mod-2LLu);
//printf("inv:%llu\n",inv);
//printf("%llu\n",3741175000LLu%mod);
ll a=(p*inv)%mod;
ll b=((1000LLu-p)*inv)%mod;
//printf("a:%llu\n",a);
//printf("b:%llu\n",b);
a=qmod(a,k);
b=qmod(b,n-k);
//printf("new a:%llu\n",a);
//printf("new b:%llu\n",b);
ans=(a*b)%mod;
//printf("ans:%llu\n",ans);
ll t=k-1;
ll tmp=1LLu;
ll ta=n-1,tb=k-1;
while(t--)
{
tmp=tmp*ta%mod;
tmp=tmp*qmod(tb,mod-2)%mod;
ta--;
tb--;
}
tmp=tmp%mod;
while(tmp<=0)
tmp+=mod;
//printf("tmp:%llu\n",tmp);
ans=ans*tmp%mod;
while(ans<0)
ans+=mod;
printf("%llu\n",ans);
return 0;
}