Skip to main content

NT Part 1:GCD, LCM, Euclidean Algorithm

 The definitions of GCD and LCM are well-known, (and taught in middle school I think) I will skip the definitions.

Also, since $\text{lcm} (a,b) \cdot \text{gcd} (a,b) = ab$, calculating GCD is equivalent to calculating LCM.
Now, how do we calculate the GCD of two numbers?

A naive solution would be iterating over all positive integers no more than $\text{min} (a,b)$.
This will get the GCD in $O(\text{min}(a,b))$, very very slow.

We can calculate the GCD of $a,b$ in $O(\log ab)$ using Euclidean Algorithm.
This algorithm uses the easy-to-prove fact $\text{gcd}(a,b) = \text{gcd} (b, r)$, where $r$ is the remainder when $a$ is divided by $b$, or just a%b.

We can now use the following code.

#include <iostream>
using namespace std;
int gcd(int u, int v)
{
    return u%v==0?v:gcd(v,u%v);
}
int main(void)
{
    int x, y;
    cin>>x>>y;
    cout<<gcd(x,y);
}


How do we prove that this algorithm is $O(\log ab)$? Well, let's suppose that we started with $(a,b)$.
Then, we go to $(b,r)$, where $r$ is defined similarly as above. It can be proved that $br < \frac{1}{2}ab$.
Therefore, the product of two numbers in the function decreases by half every time. Done!

Here's a challenge. Can we find the numbers $x, y$ such that $ux+vy=\text{gcd} (u,v)$?
There exists infinitely many pairs - this is Bezout's Lemma. The algorithm to generate such pairs is called Extended Euclidean Algorithm.

Comments

Popular posts from this blog

NT Part 6: Sieve of Eratosthenes(Details)

  About 2300 years ago from today, famous Greek mathematician Euclid proved that there are an infinite number of prime numbers. Since then people have been searching for these prime numbers. In 1849, one of the greatest mathematician of all time, Carl Fredrick Gauss, had identified almost all of the prime numbers within the first 3 hundred thousand whole numbers. In the age of computers, we can find large prime numbers in the blink of an eye. But to do that, we need to know a bit of programming and a 2000 year old algorithm. By the end of this tutorial, you will be able to figure out a solution on your own to Gauss’s problem. What is a Prime Number? A prime number is an integer number that is divisible by 1 and the number itself only. For example, 7 is divisible by 1 and 7 only. But 6 is not a prime number because 6 is be divisible by 2 and 3 as well. It is worth mentioning that 1 itself is not a prime number. Now if you are asked to determine if a number is a prime number, you can...

Binary Search & The Kahini!

  Suppose you are given an array of numbers and you need to find whether the number X is in the array. The straight forward approach to do that would be to run a loop and compare each number in the array with X. This is what the pseudo code would look like: function findNumber ( A , x ) for i = 0 to length of array A if A [ i ] == x return true return false For example, let’s assume you are given this array: [7, 14, 17, 21, 35, 60, 92, 121, 155] And, you were looking for the number 92. The loop would start checking each of the number in the array against 92 and would find after iterating through the array 7 times. The worst case time complexity of this approach would be O(n). However, whenever the array itself is in sorted order (like in this case where the numbers are increasing in value from left to right of the array), you can perform something that is much more efficient: binary search. The prerequisite of binary search is that the array should be sor...

NT Part 3: Playing with Modulars, and Euler Phi Function

  Quick stuff first, fast exponentiation in logarithm time. Let us calculate   in modular   in  . It uses binary expansion of  ,  and is very very straightforward. ll exp ( ll x, ll n ) { if ( n == 0 ) return 1 ; if ( n == 1 ) return x ; if ( n % 2 == 0 ) return exp ( ( x * x ) % mod,n / 2 ) ; if ( n % 2 == 1 ) return ( x * exp ( ( x * x ) % mod,n / 2 ) ) % mod ; } Now, let us talk about modular inverses. By using Extended Euclidean Algorithm, we can get the inverse of   modulo  . #include <iostream> int inv ( int a, int m ) { int temp = m, q, t, u = 0 , v = 1 ; if ( m == 1 ) return 0 ; while ( a > 1 ) { q = a / m ; t = m ; m = a % m ; a = t ; t = u ; u = v - q * u ; v = t ; } if ( v < 0 ) v + = temp ; return v ; } int main ( void ) { int a, m ; std :: cin ...