15. GCD and LCM
The GCD (greatest common divisor) and the LCM (least common multiple) appear in OSN problems in many disguises: splitting items evenly, simplifying fractions, finding when two events repeat at the same time. This chapter covers how to compute them quickly.
Definitions
- GCD(a, b) is the largest number that divides both
aandbexactly. - LCM(a, b) is the smallest positive number that is
divisible by both
aandb.
Example for 12 and 18:
| Number | Divisors | Multiples |
|---|---|---|
| 12 | 1, 2, 3, 4, 6, 12 | 12, 24, 36, 48, … |
| 18 | 1, 2, 3, 6, 9, 18 | 18, 36, 54, … |
Greatest common divisor: 6. Least common multiple: 36.
The primary-school method — factor into prime numbers, take the
smallest exponent for the GCD and the largest for the LCM — is correct,
but slow: for a up to 10¹⁸, the factoring alone already
takes far too long.
The Euclidean algorithm
The fast method is more than two thousand years old and uses only one property:
GCD(a, b) = GCD(b, a mod b), and GCD(a, 0) = a.
The reason: every common divisor of a and b
also divides a − b, and therefore also divides
a mod b. So the set of common divisors does not change,
while the numbers shrink quickly.
A helpful picture: imagine an a × b rectangle that you
want to cover with equal square tiles without cutting any. Cut off as
many b × b squares as possible from one end; the leftover
piece measures (a mod b) × b. The tiles that can cover the
original rectangle are exactly the tiles that can cover the leftover —
because the part that was cut off can certainly be covered. Repeating
the cutting until nothing is left gives the largest tile size, which is
the GCD.
Trace GCD(48, 18):
a |
b |
a mod b |
|---|---|---|
| 48 | 18 | 12 |
| 18 | 12 | 6 |
| 12 | 6 | 0 |
| 6 | 0 | — |
The answer is 6.
Recursive version:
long long fpb(long long a, long long b) {
if (b == 0) return a;
return fpb(b, a % b);
}Loop version:
long long fpb(long long a, long long b) {
while (b != 0) {
long long sisa = a % b;
a = b;
b = sisa;
}
return a;
}One more example, GCD(1071, 462):
a |
b |
a mod b |
|---|---|---|
| 1071 | 462 | 147 |
| 462 | 147 | 21 |
| 147 | 21 | 0 |
| 21 | 0 | — |
The answer is 21. Notice how fast the numbers shrink: every two steps, the larger number is at least halved.
The number of steps is O(log min(a, b)) — even for numbers as large as 10¹⁸ it is fewer than 90 steps. The most "stubborn" pair is two consecutive Fibonacci numbers: for 1,134,903,170 and 701,408,733, the algorithm needs 43 steps, and that is already the worst case in the billions range. Compare that with the primary-school method, which has to factor both numbers first — for numbers that large, the factoring alone takes far longer than the entire Euclidean algorithm.
C++ provides __gcd(a, b) (from
<algorithm>) and gcd(a, b) (from
<numeric>, since C++17). Both may be used in
contests. Still understand how it works: problems often ask for
variations that the library does not provide, such as the extended GCD
at the end of this chapter.
Open
exercises/15/01-fpb.cpp.
The program prints every step of the Euclidean algorithm. Run it for
48 18, then for two large consecutive Fibonacci numbers
such as 1134903170 701408733 — that is the kind of pair
that makes Euclid work the longest.
LCM from the GCD
The property that connects the two:
GCD(a, b) × LCM(a, b) = a × b
So:
long long kpk(long long a, long long b) {
return a / fpb(a, b) * b; // divide first, then multiply
}Check with the example 12 and 18: the GCD is 6, and 12 / 6 × 18 = 2 × 18 = 36 — it matches the table at the start of the chapter.
Open
exercises/15/02-kpk.cpp.
Inside kpk_aman ("safe LCM"), change the order of
operations to a * b / fpb(a, b), recompile, and watch the
line KPK besar change from 12000000000 to
2776627963 — a * b overflows before it can be
divided.
The order of operations matters. a * b / fpb(a, b) gives
the same answer mathematically, but a * b can overflow
before the division. By dividing first, the intermediate result stays
small. The division is always exact because the GCD always divides
a exactly.
GCD and LCM of many numbers
Both can be computed in sequence:
long long g = a[0];
for (int i = 1; i < n; i++) g = fpb(g, a[i]);
long long k = a[0];
for (int i = 1; i < n; i++) k = kpk(k, a[i]);The running GCD is safe, and can even stop early: once the value reaches 1, the result cannot change anymore.
The running LCM overflows quickly: the LCM of 1
through 20 is already 232,792,560, and the LCM of 1 through 43 already
exceeds the long long limit. That is why problems usually
ask for the LCM modulo some number, or restrict the data.
Problem patterns
Simplifying a fraction. Divide the numerator and denominator by their GCD.
long long g = fpb(p, q);
cout << p / g << "/" << q / g << "\n";Repeating events. Lamp A blinks every 12 seconds, lamp B every 18 seconds. They blink together every LCM(12, 18) = 36 seconds.
Splitting evenly. There are 48 candies and 18 chocolates, distributed evenly with nothing left over among as many children as possible: GCD(48, 18) = 6 children.
Square tiles. A 48 × 18 cm floor is covered with equal square tiles without cutting any: the largest side is GCD(48, 18) = 6 cm.
Coprime numbers. a and b
are called coprime if GCD(a, b) = 1. This is a condition that comes up
often, for example with the modular inverse.
The extended Euclidean algorithm
An advanced version that not only computes the GCD, but also finds
x and y satisfying:
a·x + b·y = GCD(a, b)
long long fpb_luas(long long a, long long b, long long &x, long long &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
long long x1, y1;
long long g = fpb_luas(b, a % b, x1, y1);
x = y1;
y = x1 - (a / b) * y1;
return g;
}For example, for a = 3 and b = 7: the
algorithm produces x = -2 and y = 1, and
indeed 3 × (−2) + 7 × 1 = 1. Since the term 7 · y
contributes nothing modulo 7, this means 3 × (−2) ≡ 1 (mod 7), so the
inverse of 3 modulo 7 is −2, which is normalized to
((-2 % 7) + 7) % 7 = 5. Check: 3 × 5 = 15 = 2 × 7 + 1.
Correct.
What it is for: finding the modular inverse when the modulus is
not a prime number, so Fermat's little theorem (Chapter
14) does not apply. If GCD(a, m) = 1, then from
a·x + m·y = 1 we get a·x ≡ 1 (mod m), so
x is the inverse of a.
For OSN at the regency and province levels, the GCD, LCM, and the ordinary Euclidean algorithm are enough. Extended Euclid is introduced here so you know there is a way out when the modulus is not prime — not to be memorized now.
Open
exercises/15/03-euclid-luas.cpp.
The program finds x and y for the pair
a and b that you enter, then checks that
a·x + b·y really equals the GCD.
Homework
Problem 1 — GCD and LCM
Open
exercises/15/homework/01-fpb-kpk.cpp.
Read two positive integers (up to 10¹⁸), print their GCD on the first
line and their LCM on the second. The LCM is guaranteed to fit in
long long.
Problem 2 — Simplify a fraction
Open
exercises/15/homework/02-pecahan.cpp.
Read the numerator p and denominator q (both
positive), print the fraction in lowest terms in the form
p/q.
Problem 3 — GCD of a sequence of numbers
Open
exercises/15/homework/03-fpb-deret.cpp.
Read n (≤ 200,000) then n numbers. Print the
GCD of all of them. Hint: running GCD, and once the value reaches 1, the
answer will not change anymore.
Problem 4 — Blinking lamps
Open
exercises/15/homework/04-lampu.cpp.
Read n (≤ 15) then n blink intervals (each ≤
1,000). All lamps blink together at second 0. Print the next second at
which they all blink together. The answer is guaranteed to fit in
long long.
Challenge — Modular inverse without Fermat
Open
exercises/15/homework/05-invers-euclid.cpp.
Read a and m (m need not be
prime). If GCD(a, m) ≠ 1, print TIDAK ADA. Otherwise, print
the inverse of a modulo m using the extended
Euclidean algorithm, then print the result of the check
a × inverse mod m (must be 1).
Most common mistakes
| What was written | Consequence |
|---|---|
a * b / fpb(a, b) |
overflows before dividing; write a / fpb(a, b) * b |
fpb of type int for 10¹⁸ data |
wrong answer |
| running LCM of many numbers | overflow; problems usually restrict the data |
forgetting the b == 0 case |
infinite recursion |
| GCD used when the LCM is asked for | "when do they repeat together" is LCM, "what is the largest number of groups" is GCD |
| Fermat's theorem used when the modulus is not prime | wrong inverse; use extended Euclid |
OSN tips
Recognize the GCD and LCM cues in the problem statement. These two words rarely appear as-is in OSN problems; what appears is the story.
| Phrase in the problem | Tool |
|---|---|
| the largest equal-sized pieces with nothing left over | GCD |
| splitting two collections into equal-sized groups | GCD |
| a fraction reduced to lowest terms | GCD |
| when two events repeat together again | LCM |
| the smallest number divisible by all of them | LCM |
| divisible by both X and Y | LCM |
Write the LCM as a / fpb(a, b) * b, not
a * b / fpb(a, b). Both are mathematically
correct, but the second form computes a * b first and can
overflow even when the LCM itself is small. Dividing first always works
exactly, because the GCD always divides a exactly.
The LCM can explode, the GCD never does. The GCD is never larger than the smallest number, but the LCM of several numbers can grow very fast: the LCM of 1 through 20 alone is already more than 2 × 10⁸. If a problem asks for the LCM of many numbers without a modulo, check the constraints — often what is actually asked is the answer modulo something, or the constraints really are small.
The Euclidean algorithm is very fast, so do not replace it. Finding the GCD by trying every divisor takes up to 10⁹ steps for numbers that large; Euclid finishes in tens of steps. The difference is not an optimization, but the difference between possible and impossible.
The GCD of a sequence of numbers is computed step by
step. fpb(a, b, c) equals
fpb(fpb(a, b), c), and this property holds for any number
of values. The correct initial value is 0, because
fpb(0, x) = x. Starting from 1 is a mistake that makes
every answer 1.
Differences are a hidden hint. A problem that says
"all the numbers leave the same remainder when divided by
d" is really talking about differences: d must
divide every difference exactly. This change of viewpoint turns a
problem that looks hard into a single line of GCD.
C++17 already provides gcd(a, b) and
lcm(a, b) in <numeric>. Both may be used
in contests that allow C++17, but write the Euclid version yourself at
least once until you know it by heart — the built-in functions do not
save you when the problem requires extended Euclid.
Summary
- GCD(a, b) is the greatest common divisor, LCM(a, b) the least common multiple.
- Euclidean algorithm: GCD(a, b) = GCD(b, a mod b), stopping when
b = 0. It takes O(log min(a, b)) steps. - The LCM is computed from the GCD:
a / fpb(a, b) * b— divide first, then multiply, so it does not overflow. - The running GCD is safe and can stop as soon as it reaches 1; the running LCM overflows quickly.
- The problem patterns: simplifying fractions (GCD), events repeating together (LCM), splitting evenly into as many groups as possible (GCD), the largest square tile (GCD).
- Extended Euclid finds
xandyina·x + b·y = GCD(a, b), and is used for the modular inverse when the modulus is not prime.
OSN-style exercises
None of the following three problems mention the words GCD or LCM. That is exactly what is being practiced: recognizing the intended tool from the wording of the story.
The skeletons for all three are in
exercises/15/osn/.
Problem 1 — Largest Square Tile
A rectangular floor measuring P × L
centimeters is to be covered with square tiles that are all the same
size. Tiles may not be cut, may not overlap, and the floor must be
covered completely with nothing left over.
Determine the largest tile side that satisfies these conditions, and how many tiles are used.
Input format. One line containing two integers
P and L.
Output format. One line containing two integers: the largest tile side and the number of tiles, separated by a single space.
Constraints. 1 ≤ P, L ≤
10⁹.
Sample input
12 18
Sample output
6 6
Explanation. The tile side must divide both 12 and 18 exactly. The possible choices are 1, 2, 3, and 6; the largest is 6. With 6 × 6 tiles, the floor is divided into 2 × 3 = 6 tiles.
The skeleton:
exercises/15/osn/01-ubin-persegi.cpp
Problem 2 — Common Multiples
A factory has two machines. The first machine beeps at every second
that is a multiple of X, and the second machine at every
second that is a multiple of Y. Count how many seconds
between second A and second B, inclusive, both
machines beep at the same time.
Input format. One line containing four integers
A, B, X, and Y.
Output format. One line containing the number of such seconds.
Constraints.
- 1 ≤
A≤B≤ 10¹⁸ - 1 ≤
X,Y≤ 10⁹
Sample input
1 100 4 6
Sample output
8
Explanation. Both machines beep together at seconds
12, 24, 36, 48, 60, 72, 84, and 96 — there are eight. Note the
constraint on B: checking every second one by one is
impossible.
The skeleton:
exercises/15/osn/02-kelipatan-bersama.cpp
Problem 3 — Common Divisor of Differences
You are given N integers. Find the largest positive
integer d such that all the numbers leave the same
remainder when each is divided by d.
If all the numbers are exactly equal, d can be any
value; for that case print 0.
Input format. The first line contains an integer
N. The second line contains N integers.
Output format. One line containing the largest
d, or 0 for the special case above.
Constraints.
- 2 ≤
N≤ 200,000 - 1 ≤
Aᵢ≤ 10¹⁸
Sample input
3
5 11 17
Sample output
6
Explanation. With d = 6, all three
numbers leave remainder 5. There is no larger d that gives
the same remainder for all three.
The skeleton:
exercises/15/osn/03-pembagi-selisih.cpp
Stuck or already done? Open the homework solutions page.