ICPC Assiut Community Newcomers Training
Math
Topics
Modular Arithmetic
Z is the smallest non negative number such that X - Z is multiple of Y
it also mean that : Q * Y + Z = X (Q is any number)
so that X - Z = Q * Y
it mean 17 - 1 = 16, and 16 is divisible by 4
also 4 * 4 + 1 = 17, 17 - 1 = 4 * 4 = 16
Modular Arithmetic
Ex : 19 % 4 = 3
Ex : 4 % 6 = 4
Ex : 8 % 8 = 0
4) X = 0
Ex : 0 % 5 = 0
5) Y = 0
Ex : 5 % 0 = RuntimeError
Modular Arithmetic Properties
Take %5 to every number in the given list :
List : 0 1 2 3 4 5 6 7 8 9
Mod: 0 1 2 3 4 0 1 2 3 4
Modular Arithmetic Properties
Ex:
(4 * 8) % 3 = 32 % 3 = 2
((4 % 3) * (8 % 3)) % 3 = (1 * 2) % 3 = 2 % 3 = 2
Modular Arithmetic Code
// Cycling Pattern
#include<iostream>
using namespace std;
int main () {
int a, b;
a = 13;
b = 5;
for(int i=0;i<=a;i++){
cout << i << " >> " << i % b << endl;
}
return 0;
}
Output :
0 >> 0
1 >> 1
2 >> 2
3 >> 3
4 >> 4
5 >> 0
6 >> 1
7 >> 2
8 >> 3
9 >> 4
10 >> 0
11 >> 1
12 >> 2
13 >> 3
Factorization
Ex :
if (X % Y = 0) , so Y is a factor of X
But, Is that the best way !?
What if X is a Large Number !?
Factorization Optimization
The marked numbers is the factors : 1 2 3 4 5 6 7 8 9 10 11 12
if (i == 1), the factors is { i, N / i } = {1, 12}
if (i == 2), the factors is { i, N / i } = {2, 6}
if (i == 3), the factors is { i, N / i } = {3, 4}
if (i == 4), the factors is {4, 3} But we already have this factors, so we don`t need to continue the remaining numbers, because it will repeat the factors
Factorization Code
// Factors of N
#include<iostream>
using namespace std;
int main () {
int N = 36;
// i <= sqrt(N) >> Square both sides >> i * i <= N
// sqrt(N) take O(log(N)) , i * i take O(1), so it is faster
for(int i = 1; i * i <= N; i++){
if(N % i == 0){
cout << i << " ";
// if (i * i == N) you just need to print (i) not (N / i)
if(i * i != N){
cout << N / i << " ";
}
}
}
return 0;
}
Output:
1 36 2 18 3 12 4 9 6
Prime Factorization
( n = 1 ) >> not prime >> factors {1}
( n = 2 ) >> prime >> factors {1, 2}
( n = 3 ) >> prime >> factors {1, 3}
( n = 4 ) >> not prime >> factors {1, 2, 4}
( n = 5 ) >> prime >> factors {1, 5}
( n = 6 ) >> not prime >> factors {1, 2, 3, 6}
( n = 7 ) >> prime >> factors {1, 7}
Prime Factorization
N = 18
2 * 9
2 * 3 * 3
The Prime factors is {2, 3}
N = 30
2 * 15
2 * 3 * 5
The Prime factors is {2, 3, 5}
Prime Factorization Code
// Prime Factorization of N
#include<iostream>
using namespace std;
int main () {
int N;
cin >> N;
// i <= sqrt(N) >> Square both sides >> i * i <= N
// sqrt(N) take O(log(N)) , i * i take O(1), so it is faster
for(int i = 2; i * i <= N; i++){
while(N % i == 0){
cout << i << " ";
N /= i;
}
}
if(N > 1){ // To Handle if N is a prime number
cout << N << endl;
}
return 0;
}
Output:
2 2 3 3
Problems
Greatest Common Divisor (GCD)
Ex:
gcd(20, 15) = 5
gcd(8, 8) = 8
gcd(6, 3) = 3
gcd(11, 7) = 1
gcd(5, 0) = 5
Greatest Common Divisor (GCD)
Ex:
the gcd(30, 45) = 15
the prime factors of (30) : 2 * 3 * 5
the prime factors of (45) : 3 * 3 * 5
it is :
3 : 1 times
5 : 1 times
so the gcd(30, 45) = the multiple of the common prime factors between them = 3 * 5 = 15
Greatest Common Divisor (GCD)
the gcd(75, 450) = 75
the prime factors of (75) : 3 * 5 * 5
the prime factors of (450) : 2 * 3 * 3 * 5 * 5
it is :
3 : 1 times
5 : 2 times
so the gcd(75, 450) = the multiple of the common prime factors between them = 3 * 5 * 5 = 75
GCD Code
#include<iostream>
using namespace std;
int gcd(int a, int b){
// gcd(a, b) = gcd(b, a % b)
// the condition stop if b = 0
while(b != 0){
int x = a;
a = b;
b = x % b;
}
return a;
}
int main () {
int a = 20, b = 15;
//cin >> a >> b;
cout << gcd(a, b);
return 0;
}
// In CodeBlocks there is a function __gcd() that take two integers and return the GCD
5
�You are given a river with a series of consecutive logs starting from the first log at the beginning of the river and extending to the opposite bank. The distances between the logs are provided. Your task is to jump from the first log to the last log.
Game Rules:
Goal:
Practice Time !
Least Common Multiple (LCM)
Ex :
Least Common Multiple (LCM)
Ex :
lcm(45, 30) = 90
the prime factors of 45 : 3 * 3 * 5
the prime factors of 30 : 2 * 3 * 5
2 : 1 times in 30 > 0 times in 45 (we take 2 with 1 times)
3 : 1 times in 30 < 2 times in 45 (we take 3 with 2 times)
5 : 1 times in 30 = 1 times in 45 (you can take any of them)
Least Common Multiple (LCM)
the lcm(8, 3) = 24
the prime factors of (3) : 3
the prime factors of (8) : 2 * 2 * 2
it is :
3 : 1 times
2 : 3 times
GCD & LCM Relations
the gcd(A, B) = The common prime factors = 2 * 3 * 5 * 7
the lcm(A, B) = The most frequency prime factors = 2 * 2 * 3 * 3 * 5 * 5 * 7 * 7
gcd(A, B) * lcm(A, B) = A * B >>> lcm(A, B) = (A * B) / gcd(A, B)
LCM Code
#include<iostream>
using namespace std;
int gcd(int a, int b){
// gcd(a, b) = gcd(b, a % b)
// the condition stop if b = 0
while(b != 0){
int x = a;
a = b;
b = x % b;
}
return a;
}
int lcm(int a, int b){
// gcd(a, b) * lcm(a, b) = a * b
return (a * b) / gcd(a, b);
}
int main () {
int a = 45, b = 30;
//cin >> a >> b;
cout << lcm(a, b) << endl;
return 0;
}
// In CodeBlocks there is a function __gcd() that take two integers and return the GCD
Output :
90
Now it's time to practise and solve the problems of Arrays
Good luck <3
For more information about Math Algorithms visit this Link