Number Theory #2
By Sadek Mohammed
Modular Arithmetic
We have investigated modulus (%) as a way to get the remainder after divison, but what does modulus do?
Clock Model
The easiest way to imagine the workflow of the modulus is to imagine the clock. A clock has 12 hours, where certain hours repeat. To illustrate:
- 13 pm corresponds to 1 (13 - 12) pm.
- 14 pm corresponds to 2 (14 - 12) pm.
- 12 pm corresponds to 0 (12 - 12) pm.
What can we get from that.
Imagine that you have a rotated number line, where it has the following marks: . Look at the following:
- If we move one step, we would be at place .
- If we move twelve steps, we would be at place , again.
- Start from the beginning again, and then move 5 places. You are at position 5.
- Move 24 places, you are at position 5 for the third time.
We can conclude that multiples of the modulus cause complete cycles around the number line. That means they could be eliminated when calculating the modulus.
, but how to define that correspondence in a precise way?
Division model
Any two integers and could be put in the following formula.
Some Facts:
When there is no remainder, a number could be expressed in terms of as the following . We can proof that numbers which are divisble by a third number have a difference that is divisble by that number, too.
The same holds for addition, too, by a similar proof.
Some terms:
- n dividend (the number that is divided)
- m divisor (the number that divides another one)
- q quotient (the integer part of the result of division)
- r remainder (the result of multiplying the decimal part of the divisor)
Congurence:
Two integers are said to be congruent (mod x) if they have the same remainder () when divided by x. For example:
- as and .
- as and . (Co-terminal angles).
Range of a modulus
- If you evaluate a number , you have always to output a number between and (Just think of it).
- If a number is evaluated , where m is bigger than it, the output is the number itself.
- If a number is larger than , just subtract 's till you get a number smaller than , and do the same in the previous point.
Distribution
On solving some problems, the problem statement sometimes requires that you output the answer mod a certain number as the number may get too big. For example, take the following:
Problem Statement
A certain person has a number of categories of clothes (), where each category has pieces (). You have to output the number of different combinations of clothes. (Since the number of combinations could be huge, output it )
Sample Input
3 3 2 1
Sample Output
6
Explanation of Sample
The person has 3 categories: shoes, trousers, and shirts. He has 3 shoes, 2 trousers, and a single shirt. That means that the total number of possibilities is .
How to solve ?
Look at the following code:
// Initialize the vairables (Notice that ans starts with 1)
int ans = 1, n = 0, inp = 0;
// Take the number of clothes categories
cin >> n;
while (n--)
{
// Take the number of pieces of each category
cin >> inp;
// Multiply them by the answer (1)
ans *= inp;
}
// Output the answer
cout << ans;
But there is a single problem. We need to ouptut the number . In our case, the numbers are too big. Let's do some maths.
- could reach , where that means that we need to store it in long long.
- , in the worst case could react , which is far too big to store in a -bit long long.
Fortunately, the problem statement is the supreme savior. If we take the answer repeatedly , we would always obtain an answer that is always less than that perfectly fits in a normal -bit integer. To do so we need to have some knowledge about the distribution of operations.
Distribution Rules
Proof of distributive addition rule:
You can look for proofs for subtraction and multiplication, too.
New code
int n = 0;
// Notice that both ans and inp became long long
long long ans = 1, inp = 0;
// Note that ans is initialized by 1 (Multiplicative Identity)
cin >> n;
while (n--)
{
cin >> inp;
// Take inp mod
inp %= mod;
ans *= inp;
// Take ans mod
ans %= mod;
}
cout << ans;
Notice the following:
- inp should be long long as it has an upper bound of .
- ans should be long long because of the third line in the loop.
- We should take the mod each time to satisfy the following equation.
Modulus of negative numbers
Taking modulus of negative numbers differs according to the language; however, in cpp, we do the following:
- Take the normal modulus.
- Add the value of the modulus.
- Retaking the normal modulus.
int all_mod (int n, int m)
{
return ((n % m) + m) % m;
}
This method works for positive numbers, too. That's because all we do is neglecting the multiples of the modulus as in the clock model.
The greatest common divisor.
What is the gcd.
Imagine the following numbers:
In the previous session, we have observed that 12 must have 6 divisors: . On the contrary, 8 must have 4 divisors: .
We could observe that they have 3 common divisors: . The greatest commond divisor (gcd) is .
How could I find the gcd of two numbers?
Let a be a number with prime divisors: and b be a number with the following divisors: . Let their gcd be c.
How to do that on a computer?
Euclidean Theorem.
Since each number that divides and divides their difference . We can find the gcd this way:
Extended Euclidean Theorem.
If you could remember the clock model, we were extensively subtracting 12s from the hour to get its counterpart in the range . The same goes with a great improvement to the euclidean theorem.
Code
The extended euclidean algorithm can be implemented as follows:
int gcd(int a, int b)
{
if (a < b)
{
swap(a, b);
}
if (b == 0)
{
return 0;
}
return gcd(b, a%b);
}
The least common multiple.
What is the lcm?
See the following:
- Multiples of 14:
- Multiples of 35:
There can be common multipes: 70, 140, etc; however, the least one of them is .
But how could that happen?
Observe the following:
- LCM: .
- Another common multiple: 140: .
How could I find the gcd of two numbers?
Let a be a number with prime divisors: and b be a number with the following divisors: . Let their gcd be c.
How to do that on a computer?
When we take the gcd for two numbers like 42 and 28 .
Their GCD & LCM
Let's look at the exponents of the prime factors:
- 2: 42 has 1 as the exponent while 28 has 2 as the exponent.
- 3: 42 has 1 as the exponent while 28 has 0 as the exponent.
- 7: Both 42 and 7 has 1 as the exponent.
This implies that:
- Since GCD uses the minimums, the GCD = , which is 14.
- Since LCM uses the maximums, the LCM = , which is 84.
Let's look at the following:
- 42: .
- 28: .
- 14 (GCD): .
- 84 (LCM): .
- 1176 (): ).
It can be concluded that result of multiplying the two numbers has all their factors, GCD has the minimum factors only, and LCM has the maximum factors, so if we can find the GCD and a way to remove the minimum factors, we could find the maximum factors, lcm.
When using this with the above way of calculating the gcd, the process becomes very efficient.