Math + Greedy
UMD Competitive Programming Club Week 3
Number Theory
1. How to factorize a number?
Suppose there is a integer \(n\), how would you factorize this number?
1. How to factorize a number?
Suppose there is a integer \(n\), how would you factorize this number?
Go through all numbers less than \(n\)?
vector<int> v;
for(int i = 2; i <= n; i++){
while(n % i == 0){
v.push_back(i);
}
}
1. How to factorize a number?
Go through all numbers less than \(n\)?
vector<int> v;
for(int i = 2; i <= n; i++){
while(n % i == 0){
v.push_back(i);
n /= i;
}
}
1. How to factorize a number?
Go through all numbers less than \(n\)?
What would happen if \(n\) is prime?
vector<int> v;
for(int i = 2; i <= n; i++){
while(n % i == 0){
v.push_back(i);
n /= i;
}
}
1. How to factorize a number?
Go through all numbers less than \(n\)?
What would happen if \(n\) is prime?
Time: \(O(n)\)
vector<int> v;
for(int i = 2; i <= n; i++){
while(n % i == 0){
v.push_back(i);
n /= i;
}
}
1. How to factorize a number?
Go through all numbers less than \(\sqrt{n}\) ?
vector<int> v;
for (int i = 2; i * i <= n; i++) {
while (n % i == 0) {
v.push_back(i);
n /= i
}
}
if (n != 1) {
v.push_back(n);
}
Time: \(O(\sqrt{n})\)
1. How to factorize a number?
Can we do better?
YES!
2. How to check if a number is prime?
2. How to check if a number is prime?
Suppose the constraint is
and you need to factorize multiple numbers!
2. How to check if a number is prime?
What if we have a table of whether each number are prime?
2. How to check if a number is prime?
What are prime numbers?
The only divisors are \(1\) and itself!
2. How to check if a number is prime?
2. How to check if a number is prime?
\(2\) is a prime! Eliminate it's multiples!
2. How to check if a number is prime?
\(3\) is a prime! Eliminate it's multiples!
2. How to check if a number is prime?
\(5\) is a prime! Eliminate it's multiples!
2. How to check if a number is prime?
This is called the Sieve of Erathosthenes
2. How to check if a number is prime?
This is called the Sieve of Erathosthenes
bool isPrime[n+1];
fill(isPrime, isPrime+n+1, true);
isPrime[1] = false;
for(int i = 2; i <= n; i++){
if(!isPrime[i]) continue;
for(int j = i; j <= n; j += i){
isPrime[j] = false;
}
}
2. How to check if a number is prime?
This is called the Sieve of Erathosthenes
bool isPrime[n+1];
fill(isPrime, isPrime+n+1, true);
isPrime[1] = false;
for(int i = 2; i <= n; i++){
if(!isPrime[i]) continue;
for(int j = i; j <= n; j += i){
isPrime[j] = false;
}
}
2. How to check if a number is prime?
Can this be even faster?
YES!
2. How to check if a number is prime?
Let \(lpf[i]\) be the Least Prime Factor of \(i\)
For example,
\(lpf[10] = 2 \\ lpf[33] = 3 \\ lpf[11] = 11\)
2. How to check if a number is prime?
Suppose a number \(p\) is prime, then we have
\(lpf[p] = p\)
2. How to check if a number is prime?
Then we can do this
int lpf[N]; vector<int> primes;
fill(lpf,lpf+N,1);
for(int i = 2;i < N;i++){
if(lpf[i]==1){
lpf[i] = i;
primes.push_back(i);
}
for(int x : primes){
if(x*i > N) break;
lpf[x*i]=x;
if(x==lpf[i]) break;
}
}
Time: \(O(n)\) (prove this)
2. How to check if a number is prime?
With the LPF function,
we can actually factorize a number
in \(O(\log n)\)!
1. How to factorize a number?
vector<int> factors;
while (lpf[x] != 1) {
factors.push_back(lpf[x]);
x /= lpf[x];
}
This takes \(O(\lg n)\) since the worst case is \(n = 2^k\) for some \(k \in \mathbb{N}\)
2. How to check if a number is prime?
There is also the Miller Rabin primal test
and the Pollard Rho for factorizing
They are much faster than what we just talked about lol
KACTL has good template
3. Modular Congruence
3. Modular Congruence
You will often seen this in problem statement
Since the answer could be large,
output the answer modulo \(10^9+7\)
Therefore, we need to know how modulo works
3. Modular Congruence
Under modulo, these three operations hold
But division does not!!!
3. Modular Congruence
To do division under modulo, we need
Modular Inverse!
3. Modular Congruence
Def. \(b\) is modular inverse of \(a\) under modulo \(m\) if
\(ab \equiv 1 \pmod m\)
Â
We write \(b\) as \(a^{-1}\)
3. Modular Congruence
There are three common ways in CP
- Fermat's Little Theorem
- A cool recurrence
- Extended Euclidean Theorem
3-1. Binary Exponentiation
3-1. Binary Exponentiation
Suppose you want to find
How will you do this?
3-1. Binary Exponentiation
Calculate with a for loop?
3-1. Binary Exponentiation
What will you do if you want to calculate
3-1. Binary Exponentiation
3-1. Binary Exponentiation
3-1. Binary Exponentiation
You only do this \(O(\lg n)\) times!
3-1. Binary Exponentiation
What if now \(n \ne 2^k\) ?
3-1. Binary Exponentiation
Since \(a^{\lfloor n/2 \rfloor}\) are the same
We have
3-1. Binary Exponentiation
Since \(a^{\lfloor n/2 \rfloor}\) are the same
We have
3-1. Binary Exponentiation
Another way
3-1. Binary Exponentiation
Convert \(n\) to binary!
If \(p\) is a prime, and \(\gcd(a,p) = 1\)
From number theory, we have
3-2-1. Fermat's Little Theorem
3-2-1. Fermat's Little Theorem
3-2-1. Fermat's Little Theorem
If \(p\) is prime,
do binary exponentiation!
3-2-2. A Recurrence
From the following identity
Take mod \(p\) on both sides!
3-2-2. A Recurrence
3-2-2. A Recurrence
3-2-2. A Recurrence
3-2-2. A Recurrence
3-2-2. A Recurrence
Since \((p \bmod i) < i\), you can build a table
3-2-2. A Recurrence
You can find all modular inverse under \(n\) in
Bonus: What is the complexity of this recurrence?
3-2-3. Extgcd
Suppose you have an equation
Can you find integer solutions of \((x,y)\) ?
3-2-3. Extgcd
Suppose you have an equation (\(a,b,c \in \mathbb{Z}\))
Can you find integer solutions of \((x,y)\) ?
Bézout's identity: There is a solution iff
3-2-3. Extgcd
How to find a solution to
If you know \((x', y')\) to
3-2-3. Extgcd
3-2-3. Extgcd
3-2-3. Extgcd
3-2-3. Extgcd
pair<int,int> extgcd(int a, int b){
if (b == 0) return {1, 0};
else if (a == 0) return {0, 1};
auto [x,y] = extgcd(b, a % b);
return {y,x - a / b * y};
}
3-2-3. Extgcd
To find modular inverse, find the solution to
You can apply Extgcd!
This works when \(m\) is not prime!
3-3. Mod Int
3-3. Mod Int
If you can use templates, you don't really need to care about these
3-3. Mod Int
If you can use templates, you don't really need to care about these
4. Chinese Remainders Theorem
You want to solve
4. Chinese Remainders Theorem
4. Chinese Remainders Theorem
4. Chinese Remainders Theorem
Apply ExtGcd!
4. Chinese Remainders Theorem
4. Chinese Remainders Theorem
5. Binomial Coefficients
5. Binomial Coefficients
Suppose now you want to know
5. Binomial Coefficients
Two ways!
5-1. Pascal's Triangle
This can be precomputed in \(O(n^2)\)
5-2. Modular Inverse
Precompute the factorials in \(O(n)\) !
Then you can get this in \(O(\log p)\)
5. Binomial Coefficients
There is even a page on CP Algorithms
6. Linear Recurrence
6. Linear Recurrence
Suppose you want to find the \(n^{\text{th}}\) Fibonacci number
6. Linear Recurrence
Suppose you want to find the \(n^{\text{th}}\) Fibonacci number
BUT!!!!
\(n \le 10^{18}\)
6. Linear Recurrence
Suppose you want to find the \(n^{\text{th}}\) Fibonacci number
What if we write it as
6. Linear Recurrence
Binary Exponentiation!!
6. Linear Recurrence
Classic Problem. (AtCoder Link)
Suppose you have a directed graph with \(n\) vertices,
you want to find how many paths of length \(k\) there are from \(s\) to \(t\)
\(n \le 100, k \le 10^{18}\)
6. Linear Recurrence
\(n \le 100, k \le 10^{18}\)
Consider DP,
Let \(dp[i][u][v]\) be the number of paths with length \(i\) starting at \(u\) that ends at \(v\)
6. Linear Recurrence
\(n \le 100, k \le 10^{18}\)
Consider DP,
Let \(dp[i][u][v]\) be the number of paths with length \(i\) starting at \(u\) that ends at \(v\)
6. Linear Recurrence
This is actually equivalent to
6. Linear Recurrence
Therefore the answer is
This can be done in \(O(n^3 \log k)\)
Problems
Problems
Greedy
Start From The Classics
Start From The Classics
Exchange Argument!
Sort One Dimension
Undo Greedy
UMD CP Club - Math + Greedy
By sam571128
UMD CP Club - Math + Greedy
- 163