What is the fastest algorithm and the code implementation to calculate the value of the following expression?
n! / (q!)r
My code
public static double timesbyf(int n,int q,int qt,int qp1,int qp1t)
{
int totaltimes=qt+qp1t;
double ans=1.0d;
for(int i=1;i<=totaltimes;i++)
{
if(i<=qt)
{
for(int j=q;j>0;j--)
{
ans=ans*((double)n/(double)j);
n--;
}
}
else
{
for(int j=qp1;j>0;j--)
{
ans=ans*((double)n/(double)j);
n--;
}
}
}
while(n>0)
{
ans=(ans*n)%3046201;
n--;
}
return ans;
}
That is, n!
divided by q!
r
times.
I'm given that n ≤ 3 × 106 and that q < n, and it is guaranteed that (q!)r will cleanly divide n!.
I think it's a very bad idea to calculate two very large numbers and hope that the quotient comes out as something sensible.
Start by taking the natural log:
ln(n!/(q!)^r) = ln(n!) - r*ln(q!)
You can use gammaln()
for the two function values, simplify, then take exp()
to get the result you want:
value = exp(gammln(n+1) -r*gammln(q+1))
Numerical Recipes has a nice chapter on how to implement functions like gammln().