# Modular Arithmetic

Authors: Darren Yao, Michael Cao, Andi Qu, Benjamin Qi, Andrew Wang

### Prerequisites

Working with remainders from division.

Resources | |||
---|---|---|---|

IUSACO | very brief, module is based off this | ||

David Altizio | plenty of examples from math contests | ||

CPH | |||

PAPS | |||

CF | some practice probs |

## Introduction

In **modular arithmetic**, instead of working with integers themselves, we work with their remainders when divided by $m$. We call this taking modulo $m$. For example, if we take $m = 23$, then instead of working with $x = 247$, we use $x \bmod 23 = 17$. Usually, $m$ will be a large prime, given in the problem; the two most common values are $10^9 + 7$ and $998\,244\,353=119\cdot 2^{23}+1$. Modular arithmetic is used to avoid dealing with numbers that overflow built-in data types, because we can take remainders, according to the following formulas:

## Modular Exponentiation

Focus Problem – read through this problem before continuing!

### Resources

Resources | |||
---|---|---|---|

cp-algo |

**Binary exponentiation** can be used to efficently compute $x ^ n \mod m$. To do this, let's break down $x ^ n$ into binary components. For example, $5 ^ {10}$ = $5 ^ {1010_2}$ = $5 ^ 8 \cdot 5 ^ 2$. Then, if we know $x ^ y$ for all $y$ which are powers of two ($x ^ 1$, $x ^ 2$, $x ^ 4$, $\dots$ , $x ^ {2^{\lfloor{\log_2n} \rfloor}}$, we can compute $x ^ n$ in $\mathcal{O}(\log n)$.

To deal with $m$, observe that modulo doesn't affect multiplications, so we can directly implement the above "binary exponentiation" algorithm while adding a line to take results $\pmod m$.

### Solution - Exponentiation

Solution

## Modular Inverse

The **modular inverse** is the equivalent of the reciprocal in real-number arithmetic; to divide $a$ by $b$, multiply $a$ by the modular inverse of $b$. We'll only consider prime moduli $p$ here.

For example, the inverse of $2$ modulo $p=10^9+7$ is $i=\frac{p+1}{2}=5\cdot 10^8+4$. This means that for any integer $x$,

For example, $10i\equiv 5\pmod{10^9+7}$.

Resources | |||
---|---|---|---|

cp-algo | Various ways to take modular inverse, we'll only discuss the second here |

### With Exponentiation

**Fermat's Little Theorem** (not to be confused with Fermat's **Last** Theorem) states that all integers $a$ not divisible by $p$ satisfy $a^{p - 1} \equiv 1 \pmod{p}$. Consequently, $a^{p-2} \cdot a \equiv 1 \pmod{p}$. Therefore, $a^{p - 2}$ is a modular inverse of $a$ modulo $p$.

C++

int main() {ll m = 1e9+7;ll x = binpow(2,m-2,m);cout << x << "\n"; // 500000004assert(2*x%m == 1);}

Java

public class main{public static void main(String[] args) throws IOException{long m = (long)1e9+7;long x = binpow(2,m-2,m);System.out.println(x); // 500000004assert(2*x%m == 1);}}

Because it takes $\mathcal{O}(\log p)$ time to compute a modular inverse modulo $p$, frequent use of division inside a loop can significantly increase the running time of a program. If the modular inverse of the same number(s) is/are being used many times, it is a good idea to precalculate it.

Also, one must always ensure that they do not attempt to divide by 0. Be aware that after applying modulo, a nonzero number can become zero, so be very careful when dividing by non-constant values.

We can also use the extended Euclidean algorithm. See the module in the Advanced section.

## Templates

Resources | |||
---|---|---|---|

Benq | |||

Benq | feasible to type up during a contest |

Using my template, both of these do the same thing:

int main() {{int a = 1e8, b = 1e8, c = 1e8;cout << (ll)a*b%MOD*c%MOD << "\n"; // 49000000}{mi a = 1e8, b = 1e8, c = 1e8;// cout << a*b*c << "\n"; // doesn't work// ^ not silently converted to intcout << int(a*b*c) << "\n"; // 49000000}}

## Problems

Status | Source | Problem Name | Difficulty | Tags | Solution | URL |
---|---|---|---|---|---|---|

CSES | Easy | ## Show Tagsmodular arithmetic | External Sol | |||

CF | Easy | ## Show Tagsmodular arithmetic | Check CF |

### Module Progress:

### Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!

## Give Us Feedback on Modular Arithmetic!

Leave suggestions for us by making a post on the USACO Forum! Ex: Unclear sections, mislabeled problems, etc.