How to find LCM of {1, 2, ..., n} where 0 < n < 10001 in fastest possible way. The one way is to calculate n! / gcd (1,2,.....,n) but this can be slow as number of testcases are t < 501 and the output should be LCM ( n! ) % 1000000007
Code for the same is:
#include<bits/stdc++.h>
using namespace std;
#define p 1000000007;
int fact[10001] = {1};
int gcd[10001] = {1};
int main()
{
int i, j;
for( i = 2;i < 10001; i++){
fact[i] = ( i * fact[i-1]) % p;
}
for(i=2 ;i < 10001; i++){
gcd[i] =__gcd( gcd[i-1], i );
}
int t;
cin >> t;
while( t-- ) {
int n;
cin >> n;
int res = ( fact[n] / gcd[n] );
cout << res << endl;
}
return 0;
}
But this code is not performing as well. Why?
Your current solution is not correct, as has been mentioned in the comments.
One way to solve this is to realize that the LCM of those numbers is just the product of all the "largest" powers of distinct primes less than or equal to n
. That is, find each prime p
less than or equal to n
, then find the largest power of each of those primes such that it's still less than or equal to n
, and multiply those together. For a given p
, said power can be expressed in pseudocode as:
p ** math.Floor(math.Log(n) / math.Log(p))
Here's an implementation in Golang that returns immediately:
http://play.golang.org/p/8s4eE_CQ9Y
$ time go run lcm.go
5793339670287642968692270879166240098634860297998518825393138351148979300145773182308832598
<several lines later>
800000
real 0m0.225s
user 0m0.173s
sys 0m0.044s
For completeness, the full code from that playground link is pasted here:
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
n := 10001
primes := make([]int, 1, n)
primes[0] = 2
SIEVE:
for i := 3; i <= n; i++ {
for _, p := range primes {
if i%p == 0 {
continue SIEVE
}
}
primes = append(primes, i)
}
logN := math.Log(float64(n))
lcm := big.NewInt(1)
for _, p := range primes {
floatP := float64(p)
e := math.Floor(logN / math.Log(floatP))
lcm.Mul(lcm, big.NewInt(int64(math.Pow(floatP, e))))
}
fmt.Println(lcm)
}
I would calculate this in completely different way: the LCM of {1,...,n} is a product of all primes p[i]<=n, each in power floor(log(n)/log(p[i])). This product is divisible by all numbers up to n, and this is the least such number. Your main trouble is to calculate table of primes then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With