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

n \le 10^6

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?

1 \hspace{4mm} 2 \hspace{4mm} 3 \hspace{4mm} 4 \hspace{4mm} 5 \hspace{4mm} 6 \hspace{4mm} 7 \hspace{4mm} 8 \hspace{4mm} 9 \hspace{4mm} 10
11 \hspace{2.5mm} 12 \hspace{2.5mm} 13 \hspace{2.5mm} 14 \hspace{2.5mm} 15 \hspace{2.5mm} 16 \hspace{2.5mm} 17 \hspace{2.5mm} 18 \hspace{2.5mm} 19 \hspace{2.5mm} 20
21 \hspace{2.5mm} 22 \hspace{2.5mm} 23 \hspace{2.5mm} 24 \hspace{2.5mm} 25 \hspace{2.5mm} 26 \hspace{2.5mm} 27 \hspace{2.5mm} 28 \hspace{2.5mm} 29 \hspace{2.5mm} 30

2. How to check if a number is prime?

1 \hspace{4mm} 2 \hspace{4mm} 3 \hspace{4mm} 4 \hspace{4mm} 5 \hspace{4mm} 6 \hspace{4mm} 7 \hspace{4mm} 8 \hspace{4mm} 9 \hspace{4mm} 10
11 \hspace{2.5mm} 12 \hspace{2.5mm} 13 \hspace{2.5mm} 14 \hspace{2.5mm} 15 \hspace{2.5mm} 16 \hspace{2.5mm} 17 \hspace{2.5mm} 18 \hspace{2.5mm} 19 \hspace{2.5mm} 20
21 \hspace{2.5mm} 22 \hspace{2.5mm} 23 \hspace{2.5mm} 24 \hspace{2.5mm} 25 \hspace{2.5mm} 26 \hspace{2.5mm} 27 \hspace{2.5mm} 28 \hspace{2.5mm} 29 \hspace{2.5mm} 30

\(2\) is a prime! Eliminate it's multiples!

2. How to check if a number is prime?

1 \hspace{4mm} 2 \hspace{4mm} 3 \hspace{4mm} 4 \hspace{4mm} 5 \hspace{4mm} 6 \hspace{4mm} 7 \hspace{4mm} 8 \hspace{4mm} 9 \hspace{4mm} 10
11 \hspace{2.5mm} 12 \hspace{2.5mm} 13 \hspace{2.5mm} 14 \hspace{2.5mm} 15 \hspace{2.5mm} 16 \hspace{2.5mm} 17 \hspace{2.5mm} 18 \hspace{2.5mm} 19 \hspace{2.5mm} 20
21 \hspace{2.5mm} 22 \hspace{2.5mm} 23 \hspace{2.5mm} 24 \hspace{2.5mm} 25 \hspace{2.5mm} 26 \hspace{2.5mm} 27 \hspace{2.5mm} 28 \hspace{2.5mm} 29 \hspace{2.5mm} 30

\(3\) is a prime! Eliminate it's multiples!

2. How to check if a number is prime?

1 \hspace{4mm} 2 \hspace{4mm} 3 \hspace{4mm} 4 \hspace{4mm} 5 \hspace{4mm} 6 \hspace{4mm} 7 \hspace{4mm} 8 \hspace{4mm} 9 \hspace{4mm} 10
11 \hspace{2.5mm} 12 \hspace{2.5mm} 13 \hspace{2.5mm} 14 \hspace{2.5mm} 15 \hspace{2.5mm} 16 \hspace{2.5mm} 17 \hspace{2.5mm} 18 \hspace{2.5mm} 19 \hspace{2.5mm} 20
21 \hspace{2.5mm} 22 \hspace{2.5mm} 23 \hspace{2.5mm} 24 \hspace{2.5mm} 25 \hspace{2.5mm} 26 \hspace{2.5mm} 27 \hspace{2.5mm} 28 \hspace{2.5mm} 29 \hspace{2.5mm} 30

\(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;
    }
}
O(\frac{n}{2}+\frac{n}{3} + \cdots) = O(n \log \log n)

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

(a \bmod m) + (b \bmod m) \equiv a + b \pmod m
(a \bmod m)(b \bmod m) \equiv ab \pmod m
(a \bmod m) - (b \bmod m) \equiv a - b \pmod m

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

  1. Fermat's Little Theorem
  2. A cool recurrence
  3. Extended Euclidean Theorem

3-1. Binary Exponentiation

3-1. Binary Exponentiation

Suppose you want to find

a^n

How will you do this?

3-1. Binary Exponentiation

a^n = \underbrace{a \times a \times \cdots \times a}_{n \text{ times}}

Calculate with a for loop?

O(n)

3-1. Binary Exponentiation

What will you do if you want to calculate

a^8

3-1. Binary Exponentiation

a^8 = a^4 \times a^4

3-1. Binary Exponentiation

a^8 = a^4 \times a^4
a^4 = a^2 \times a^2

3-1. Binary Exponentiation

a^8 = a^4 \times a^4
a^4 = a^2 \times a^2
a^2 = a \times a

You only do this \(O(\lg n)\) times!

3-1. Binary Exponentiation

a^n

What if now \(n \ne 2^k\) ?

3-1. Binary Exponentiation

a^n = \begin{cases} a^{\lfloor n/2 \rfloor} \times a^{\lfloor n/2 \rfloor} &, n \equiv 0 \pmod 2 \\ a^{\lfloor n/2 \rfloor} \times a^{\lfloor n/2 \rfloor} \times a &, n \equiv 1 \pmod 2 \end{cases}

Since \(a^{\lfloor n/2 \rfloor}\) are the same

We have

T(n) = 2T(n/2) + O(1)

3-1. Binary Exponentiation

a^n = \begin{cases} a^{\lfloor n/2 \rfloor} \times a^{\lfloor n/2 \rfloor} &, n \equiv 0 \pmod 2 \\ a^{\lfloor n/2 \rfloor} \times a^{\lfloor n/2 \rfloor} \times a &, n \equiv 1 \pmod 2 \end{cases}

Since \(a^{\lfloor n/2 \rfloor}\) are the same

We have

T(n) = O(\lg n)

3-1. Binary Exponentiation

Another way

3-1. Binary Exponentiation

a^{15} = a^{(1111)_2} = a^8 \times a^4 \times a^2 \times a

Convert \(n\) to binary!

O(\lg n)
a^p \equiv a \pmod p

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

a^{p-2} \equiv a^{-1} \pmod p

3-2-1. Fermat's Little Theorem

a^{p-2} \equiv a^{-1} \pmod p

If \(p\) is prime,

do binary exponentiation!

O(\lg p)

3-2-2. A Recurrence

p - i \times \Big \lfloor \dfrac{p}{i} \Big \rfloor= p \bmod i

From the following identity

Take mod \(p\) on both sides!

3-2-2. A Recurrence

p - i \times \Big \lfloor \dfrac{p}{i} \Big \rfloor \equiv p \bmod i \pmod p

3-2-2. A Recurrence

p \times i - i \times \Big \lfloor \dfrac{p}{i} \Big \rfloor \equiv p \bmod i \pmod p

3-2-2. A Recurrence

i \times \left (p - \Big \lfloor \dfrac{p}{i} \Big \rfloor \right) \equiv p \bmod i \pmod p

3-2-2. A Recurrence

i \times \left (p - \Big \lfloor \dfrac{p}{i} \Big \rfloor \right) \equiv p \bmod i \pmod p
\Rightarrow (p \bmod i)^{-1} \left (p - \Big \lfloor \dfrac{p}{i} \Big \rfloor \right) \equiv i^{-1} \pmod p

3-2-2. A Recurrence

i \times \left (p - \Big \lfloor \dfrac{p}{i} \Big \rfloor \right) \equiv p \bmod i \pmod p
\Rightarrow (p \bmod i)^{-1} \left (p - \Big \lfloor \dfrac{p}{i} \Big \rfloor \right) \equiv i^{-1} \pmod p

Since \((p \bmod i) < i\), you can build a table

3-2-2. A Recurrence

(p \bmod i)^{-1} \left (p - \Big \lfloor \dfrac{p}{i} \Big \rfloor \right) \equiv i^{-1} \pmod p

You can find all modular inverse under \(n\) in

O(n)

Bonus: What is the complexity of this recurrence?

3-2-3. Extgcd

Suppose you have an equation

ax+by = c

Can you find integer solutions of \((x,y)\) ?

3-2-3. Extgcd

Suppose you have an equation (\(a,b,c \in \mathbb{Z}\))

ax+by = c

Can you find integer solutions of \((x,y)\) ?

Bézout's identity: There is a solution iff

\gcd(a,b) \ | \ c

3-2-3. Extgcd

ax+by = \gcd(a,b)
bx' + (a \bmod b) y' = \gcd(a,b)

How to find a solution to

If you know \((x', y')\) to

3-2-3. Extgcd

bx' + (a \bmod b) y' = \gcd(a,b)

3-2-3. Extgcd

bx' + (a \bmod b) y' = \gcd(a,b)
bx' + (a - b \left \lfloor \frac{a}{b} \right \rfloor) y' = \gcd(a,b)

3-2-3. Extgcd

bx' + (a \bmod b) y' = \gcd(a,b)
bx' + (a - b \left \lfloor \frac{a}{b} \right \rfloor) y' = \gcd(a,b)
ay' + b (x' - \left \lfloor \frac{a}{b} \right \rfloor y') = \gcd(a,b)
(x,y) = (y', x'-\left \lfloor \frac{a}{b} \right \rfloor y')

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};
}
O(\lg \max(a,b))

3-2-3. Extgcd

To find modular inverse, find the solution to

aa^{-1} + km = 1

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

You can write your own Modint library

or use someone else's

 

For example: AtCoder Modint Library

3-3. Mod Int

If you can use templates, you don't really need to care about these

You can write your own Modint library

or use someone else's

 

For example: AtCoder Modint Library

4. Chinese Remainders Theorem

You want to solve

\begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \end{cases}

4. Chinese Remainders Theorem

\begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \end{cases}
\text{Let } x = k_1m_1 + a_1 = k_2m_2 + a_2

4. Chinese Remainders Theorem

\begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \end{cases}
\text{Let } x = k_1m_1 + a_1 = k_2m_2 + a_2
k_1m_1 - k_2m_2 = a_2 - a_1

4. Chinese Remainders Theorem

\begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \end{cases}
k_1m_1 - k_2m_2 = a_2 - a_1

Apply ExtGcd!

4. Chinese Remainders Theorem

4. Chinese Remainders Theorem

\begin{cases} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \end{cases}
\Rightarrow x \equiv k_1m_1 + a_1 \pmod{\text{lcm}(m_1,m_2)}

5. Binomial Coefficients

5. Binomial Coefficients

Suppose now you want to know

\binom{n}{k}

5. Binomial Coefficients

\binom{n}{k}

Two ways!

5-1. Pascal's Triangle

\binom{n}{k} = \binom{n-1}{k-1} + \binom{n-1}{k}

This can be precomputed in \(O(n^2)\)

5-2. Modular Inverse

\binom{n}{k} = \frac{n!}{k!(n-k)!}

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

f_n = f_{n-1} + f_{n-2}

What if we write it as

\begin{bmatrix} f_{n+1} \\ f_n\end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0\end{bmatrix} \begin{bmatrix} f_{n} \\ f_{n-1}\end{bmatrix}

6. Linear Recurrence

\begin{bmatrix} f_{n+1} \\ f_n\end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0\end{bmatrix} \begin{bmatrix} f_{n} \\ f_{n-1}\end{bmatrix}
\implies \begin{bmatrix} f_{n} \\ f_{n-1}\end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0\end{bmatrix}^{n-1} \begin{bmatrix} f_{1} \\ f_0\end{bmatrix}

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\)

\sum_{u,v} dp[k][u][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\)

\sum_{u,v} dp[k][u][v]

6. Linear Recurrence

dp[i][u][v] = \sum_{1 \le w \le n} dp[i-1][u][w] \cdot dp[1][w][u]

This is actually equivalent to

A^{i-1}A

6. Linear Recurrence

Therefore the answer is

(A^k)_{ij}

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