Friday, 13 May 2016

number theory - Is there a more precise modified stirling's approximation formula for calculating n!?



I am trying to solve a problem of competitive programming




Consider two integer sequences f(n)=n! and g(n)=an, where n is a positive integer. For any integer a>1 the second sequence is greater than the first for a finite number of values. But starting from some integer k, f(n) is greater than g(n) for all nk. You are to find the least positive value of n for which f(n)>g(n), for a given positive integer a>1.





Constraints: 2 <= a <= 10^6
There is no constraint of n given.
Full problem statement Problem statement



I tried to solve this using Stirling's approximation formula I took log on both sides and solved it but the online judge is returning wrong answer. I wonder if there is a more precise formula or if you can suggest any new method to reduce above functions?



My code for this if that helps.



     int l = in.readInt();
int low = 1;

int high = 1000000;
int ans = 0;
double loga = Math.log10(l);
outer:
while (low <= high) {

int middle = (low + high) / 2;
double sum = 0.0;
double sum1 = 0.0;
/*

int i=1;
for (i = 1; i <= middle; i++) {
sum = sum + Math.log10(i); //This is giving TLE //Method 1

}
sum1 = sum + Math.log10(i);
sum = sum / (double) middle;
sum1 = sum1 / (double) (middle + 1.0);
*/
//Method 2

sum = ((0.5) * Math.log10(2 * Math.PI * (double) middle) + (double) middle * Math.log10(((double) middle / Math.E))) / (double) middle;
sum1 = ((0.5) * Math.log10(2 * Math.PI * ((double) middle + 1.0)) + ((double) middle + 1.0) * Math.log10((((double) middle + 1.0) / Math.E))) / ((double) middle + 1.0);
//This is giving wrong answer.


if (sum <= loga && sum1 > loga) {
ans = middle;
break outer;
} else if (sum > loga) {
high = middle - 1;


} else {
low = middle + 1;
}

}

out.printLine(ans + 1);

Answer




This is not an answer to your question, just another approach.
Using Stirling's approximation is overkill for small numbers.



Note that n!>an iff nk=1ka>1.



(Equivalently, n!>an iff nk=1lnka>0. This
avoids some issues with underflow for large a.)



def f(a):
n = 1

s = 1.0/a
while True:
if s>1:
return n
n = n+1
s = (s*n)/a

No comments:

Post a Comment

real analysis - How to find limhrightarrow0fracsin(ha)h

How to find lim without lhopital rule? I know when I use lhopital I easy get $$ \lim_{h\rightarrow 0}...