I want to find out Least Common Multiple(LCM) of more than two numbers. I know the formula of lcm(a,b) = (a * b) / gcd(a,b). Let's say, I have an array of numbers: [2, 6, 8, 13] and the the lcm should be modulo M = 1000000007.
I have seen below code to calculate the LCM of multiple numbers but I am not understanding how the calculation is going on with both the loops.
int arr[] = {2, 6, 8, 13}, n = 4
long long int ans=1;
long long int M=1000000007;
for(int i=0;i<n;i++) // Calculating LCM
{
for(int j=i+1;j<n;j++)
{
arr[j]=arr[j]/__gcd(arr[i],arr[j]);
}
ans=((ans%M)*(arr[i]%M))%M;
}
return (ans)%M;
Can anyone please help me to understand the LCM calculation in the above code?
Knowing that gcd(a, b) represents the product of all the prime factors shared by a and b, what is the significance of a / gcd(a,b)?
a / gcd(a, b) is equal to the prime factors of a that are not in b.
Therefore, when you multiple that quantity by b, you get a product of all the prime factors of b and all the prime factors of a that are not in b. This is precisely lcm(a, b).
Let's extend that to an arbitrary number of integers.
The lcm(a, b) is a times all the prime factors of b not in a or:
a * (b / gcd(a, b)) = (a * b) / gcd(a, b)
Easy enough, you knew that already.
But if we have a third number, lcm(a, b, c) is a times all the prime factors of b not in a times all the prime factors of c in neither a nor b. Well, the first part is straight forward, it's the same as above:
lcm(a, b, c) = lcm(a, b) * (all the prime factors of c in neither a nor b)
How to calculate all the prime factors of c in neither a nor b might not be obvious at first, but it's not overly complicated:
all the prime factors of c in neither a nor b = c / (gcd(a, c) * gcd(b, c))
Which means that
lcm(a, b, c) = lcm(a, b) * c / (gcd(a, c) * gcd(b, c))
lcm(a, b, c) = (a * b * c) / (gcd(a, b) * gcd(a, c) * gcd(b, c))
And now, you can generalize easily:
lcm(a[0], ..., a[N]) = prod(a[0], ..., a[N]) / pairwise_gcd(a[0], ..., a[N])
But a more relevant formulation is the recursive version:
lcm(a[0], ..., a[N]) = lcm(a[0], ..., a[N-1]) * a[N] / (gcd(a[0], a[N]) * ... * gcd(a[N-1], a[N]))
Or:
lcm(a[0], ..., a[N]) = a[0] * lcm(a[1] / gcd(a[0], a[1]), ..., a[N] / gcd(a[0], a[N]))
Here's an attempt at translating your code snippet to psuedocode
Compare this to the last definition of lcm on an array, I tried to make them appear similar.
given int array = arrayOfNums
int product := 1
for number in arrayOfNums
remove all prime factors of number from all subsequent array elements
product = product * number
product is now the lcm of arrayOfNums
Hopefully, that wasn't too confusing; I admit it may not be much of an explanation, but it is a starting point. Please let me know if anything is still unclear.
Related
In C++, I have a problem need to calculate ((a * b * c) / n) % m with large a, b and c (0 < a, b, c <= 10^9 and n, m > 0). And the problem guaranteed that a * b * c is divisible by n.
I tried calc ((a * b) % m * c) % m) / n but it's not a right answer.
Idea is to keep removing the common factors in numerator and denominator by calculating gcd and dividing it out. It is illustrated in following python code. In C++, gcd can be easily calculated using extended euclid's algorithm.
import math
def prod(a,b,c,n):
num = [a,b,c]
p = 1
tmp = n
for i in range(len(num)):
g = math.gcd(num[i],tmp)
num[i] /= g
tmp /= g
p = (p*num[i]) % n
return p
I am working on a project for school and I have run into a problem. Our goal is to calculate the last six decimal digits of the series of sums, n, i = 0, i^i using modular arithmetic. I have found a recursive method online to help me better understand how modular exponentiation works.
int exponentMod(int A, int B, int C)
{
// Base cases
if (A == 0)
return 0;
if (B == 0)
return 1;
// If B is even
long y;
if (B % 2 == 0) {
y = exponentMod(A, B / 2, C);
y = (y * y) % C;
}
// If B is odd
else {
y = A % C;
y = (y * exponentMod(A, B - 1, C) % C) % C;
}
return (int)((y + C) % C);
}
This method works fine when I am just calculating one exponent, however I'm not sure how to make this work for the problem I have been given with the series. The purpose of modular exponentiation is because we are working with large exponents, so I can not just add them up normally then mod by 1000000. I can't add up the numbers output by the above function either because they don't produce the full number that I need, when the numbers get larger, to get the correct summation. Can Someone point me in the right direction for finding the last six digits of the summation using modular arithmetic?
In my C++ code I have three uint64_tvariables:
uint64_t a = 7940678747;
uint64_t b = 59182917008;
uint64_t c = 73624982323;
I need to find (a * b) % c. If I directly multiply a and b, it will cause overflow. However, I can't apply the formula (a * b) % c = ((a % c) * (b % c)) % c, because c > a, c > b and, consequently, a % c = a, a % c = b and I will end up multiplying a and b again, which again will result in overflow.
How can I compute (a * b) % c for these values (and such cases in general) of the variables without overflow?
A simple solution is to define x = 2^32 = 4.29... 10^9
and then to represent a and b as:
a = ka * x + a1 with ka, a1 < x
b = kb * x + b1 with kb, b1 < x
Then
a*b = (ka * x + a1) * (kb * x + b1) = ((ka * kb) * x) * x
+ x * (b1 * ka) + x * (a1 * kb) + a1 * b1
All these operations can be performed without the need of a larger type, assuming that all the operations are performed in Z/cZ, i.e. assuming that % c operation is performed after each operation (* or +)
There are more elegant solutions than this, but an easy one would be looking into a library that deals with larger numbers. It will handle numbers that are too large for the largest of normal types for you. Check this one out: https://gmplib.org/
Create a class or struct to deal with numbers in parts.
Example PsuedoCode
// operation enum to know how to construct a large number
enum operation {
case add;
case sub;
case mult;
case divide;
}
class bigNumber {
//the two parts of the number
int partA;
int partB;
bigNumber(int numA, int numB, operation op) {
if(op == operation.mult) {
// place each digit of numA into an integer array
// palce each digit of numB into an integer array
// Iteratively place the first half of digits into the partA member
// Iteratively place the second half of digits into the partB member
} else if //cases for construction from other operations
}
// Create operator functions so you can perform arithmetic with this class
}
uint64_t a = 7940678747;
uint64_t b = 59182917008;
uint64_t c = 73624982323;
bigNumber bigNum = bigNumber(a, b, .mult);
uint64_t result = bigNum % c;
print(result);
Keep in mind that you may want to make result of type bigNumber if the value of c is very small. Basically this was just sort of an outline, make sure if you use a type that it won't overflow.
I want to compute nCk mod m with following constraints:
n<=10^18
k<=10^5
m=10^9+7
I have read this article:
Calculating Binomial Coefficient (nCk) for large n & k
But here value of m is 1009. Hence using Lucas theorem, we need only to calculate 1009*1009 different values of aCb where a,b<=1009
How to do it with above constraints.
I cannot make a array of O(m*k) space complexity with given constraints.
Help!
The binominal coefficient of (n, k) is calculated by the formula:
(n, k) = n! / k! / (n - k)!
To make this work for large numbers n and k modulo m observe that:
Factorial of a number modulo m can be calculated step-by-step, in
each step taking the result % m. However, this will be far too slow with n up to 10^18. So there are faster methods where the complexity is bounded by the modulo, and you can use some of those.
The division (a / b) mod m is equal to (a * b^-1) mod m, where b^-1 is the inverse of b modulo m (that is, (b * b^-1 = 1) mod m).
This means that:
(n, k) mod m = (n! * (k!)^-1 * ((n - k)!)^-1) mod m
The inverse of a number can be efficiently found using the Extended Euclidean algorithm. Assuming you have the factorial calculation sorted out, the rest of the algorithm is straightforward, just watch out for integer overflows on multiplication. Here's reference code that works up to n=10^9. To handle for larger numbers the factorial computation should be replaced with a more efficient algorithm and the code should be slightly adapted to avoid integer overflows, but the main idea will remain the same:
#define MOD 1000000007
// Extended Euclidean algorithm
int xGCD(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int x1, y1, gcd = xGCD(b, a % b, x1, y1);
x = y1;
y = x1 - (long long)(a / b) * y1;
return gcd;
}
// factorial of n modulo MOD
int modfact(int n) {
int result = 1;
while (n > 1) {
result = (long long)result * n % MOD;
n -= 1;
}
return result;
}
// multiply a and b modulo MOD
int modmult(int a, int b) {
return (long long)a * b % MOD;
}
// inverse of a modulo MOD
int inverse(int a) {
int x, y;
xGCD(a, MOD, x, y);
return x;
}
// binomial coefficient nCk modulo MOD
int bc(int n, int k)
{
return modmult(modmult(modfact(n), inverse(modfact(k))), inverse(modfact(n - k)));
}
Just use the fact that
(n, k) = n! / k! / (n - k)! = n*(n-1)*...*(n-k+1)/[k*(k-1)*...*1]
so you actually have just 2*k=2*10^5 factors. For the inverse of a number you can use suggestion of kfx since your m is prime.
First, you don't need to pre-compute and store all the possible aCb values! they can be computed per case.
Second, for the special case when (k < m) and (n < m^2), the Lucas theorem easily reduces to the following result:
(n choose k) mod m = ((n mod m) choose k) mod m
then since (n mod m) < 10^9+7 you can simply use the code proposed by #kfx.
We want to compute nCk (mod p). I'll handle when 0 <= k <= p-2, because Lucas's theorem handles the rest.
Wilson's theorem states that for prime p, (p-1)! = -1 (mod p), or equivalently (p-2)! = 1 (mod p) (by division).
By division: (k!)^(-1) = (p-2)!/(k!) = (p-2)(p-3)...(k+1) (mod p)
Thus, the binomial coefficient is n!/(k!(n-k)!) = n(n-1)...(n-k+1)/(k!) = n(n-1)...(n-k+1)(p-2)(p-3)...(k+1) (mod p)
Voila. You don't have to do any inverse computations or anything like that. It's also fairly easy to code. A couple optimizations to consider: (1) you can replace (p-2)(p-3)... with (-2)(-3)...; (2) nCk is symmetric in the sense that nCk = nC(n-k) so choose the half that requires you to do less computations.
I need to find n!%1000000009.
n is of type 2^k for k in range 1 to 20.
The function I'm using is:
#define llu unsigned long long
#define MOD 1000000009
llu mulmod(llu a,llu b) // This function calculates (a*b)%MOD caring about overflows
{
llu x=0,y=a%MOD;
while(b > 0)
{
if(b%2 == 1)
{
x = (x+y)%MOD;
}
y = (y*2)%MOD;
b /= 2;
}
return (x%MOD);
}
llu fun(int n) // This function returns answer to my query ie. n!%MOD
{
llu ans=1;
for(int j=1; j<=n; j++)
{
ans=mulmod(ans,j);
}
return ans;
}
My demand is such that I need to call the function 'fun', n/2 times. My code runs too slow for values of k around 15. Is there a way to go faster?
EDIT:
In actual I'm calculating 2*[(i-1)C(2^(k-1)-1)]*[((2^(k-1))!)^2] for all i in range 2^(k-1) to 2^k. My program demands (nCr)%MOD caring about overflows.
EDIT: I need an efficient way to find nCr%MOD for large n.
The mulmod routine can be speeded up by a large factor K.
1) '%' is overkill, since (a + b) are both less than N.
- It's enough to evaluate c = a+b; if (c>=N) c-=N;
2) Multiple bits can be processed at once; see optimization to "Russian peasant's algorithm"
3) a * b is actually small enough to fit 64-bit unsigned long long without overflow
Since the actual problem is about nCr mod M, the high level optimization requires using the recurrence
(n+1)Cr mod M = (n+1)nCr / (n+1-r) mod M.
Because the left side of the formula ((nCr) mod M)*(n+1) is not divisible by (n+1-r), the division needs to be implemented as multiplication with the modular inverse: (n+r-1)^(-1). The modular inverse b^(-1) is b^(M-1), for M being prime. (Otherwise it's b^(phi(M)), where phi is Euler's Totient function.)
The modular exponentiation is most commonly implemented with repeated squaring, which requires in this case ~45 modular multiplications per divisor.
If you can use the recurrence
nC(r+1) mod M = nCr * (n-r) / (r+1) mod M
It's only necessary to calculate (r+1)^(M-1) mod M once.
Since you are looking for nCr for multiple sequential values of n you can make use of the following:
(n+1)Cr = (n+1)! / ((r!)*(n+1-r)!)
(n+1)Cr = n!*(n+1) / ((r!)*(n-r)!*(n+1-r))
(n+1)Cr = n! / ((r!)*(n-r)!) * (n+1)/(n+1-r)
(n+1)Cr = nCr * (n+1)/(n+1-r)
This saves you from explicitly calling the factorial function for each i.
Furthermore, to save that first call to nCr you can use:
nC(n-1) = n //where n in your case is 2^(k-1).
EDIT:
As Aki Suihkonen pointed out, (a/b) % m != a%m / b%m. So the method above so the method above won't work right out of the box. There are two different solutions to this:
1000000009 is prime, this means that a/b % m == a*c % m where c is the inverse of b modulo m. You can find an explanation of how to calculate it here and follow the link to the Extended Euclidean Algorithm for more on how to calculate it.
The other option which might be easier is to recognize that since nCr * (n+1)/(n+1-r) must give an integer, it must be possible to write n+1-r == a*b where a | nCr and b | n+1 (the | here means divides, you can rewrite that as nCr % a == 0 if you like). Without loss of generality, let a = gcd(n+1-r,nCr) and then let b = (n+1-r) / a. This gives (n+1)Cr == (nCr / a) * ((n+1) / b) % MOD. Now your divisions are guaranteed to be exact, so you just calculate them and then proceed with the multiplication as before. EDIT As per the comments, I don't believe this method will work.
Another thing I might try is in your llu mulmod(llu a,llu b)
llu mulmod(llu a,llu b)
{
llu q = a * b;
if(q < a || q < b) // Overflow!
{
llu x=0,y=a%MOD;
while(b > 0)
{
if(b%2 == 1)
{
x = (x+y)%MOD;
}
y = (y*2)%MOD;
b /= 2;
}
return (x%MOD);
}
else
{
return q % MOD;
}
}
That could also save some precious time.