Skip to content

Commit

Permalink
Add document for math
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Oct 19, 2020
1 parent a8c306d commit f737533
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/math.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
//! Number-theoretic algorithms.
use crate::internal_math;

use std::mem::swap;

/// Returns $x^n \bmod m$.
///
/// # Constraints
///
/// - $0 \leq n$
/// - $1 \leq m$
///
/// # Panics
///
/// Panics if the above constraints are not satisfied.
///
/// # Complexity
///
/// - $O(\log n)$
#[allow(clippy::many_single_char_names)]
pub fn pow_mod(x: i64, mut n: i64, m: u32) -> u32 {
assert!(0 <= n && 1 <= m && m <= 2u32.pow(31));
Expand All @@ -21,13 +37,39 @@ pub fn pow_mod(x: i64, mut n: i64, m: u32) -> u32 {
r
}

/// Returns an integer $y$ such that $0 \leq y < m$ and $xy \equiv 1 \pmod m$.
///
/// # Constraints
///
/// - $\gcd(x, m) = 1$
/// - $1 \leq m$
///
/// # Panics
///
/// Panics if the above constraints are not satisfied.
///
/// # Complexity
///
/// - $O(\log m)$
pub fn inv_mod(x: i64, m: i64) -> i64 {
assert!(1 <= m);
let z = internal_math::inv_gcd(x, m);
assert!(z.0 == 1);
z.1
}

/// CRT.
///
/// Given two sequences $r, m$ of length $n$, solves the modular equation system
///
/// \\[
/// x \equiv r_i \pmod m_i, \forall i \in \\{0, 1, \cdots, n - 1\\}
/// \\]
///
/// If there is no solution, returns $(0, 0)$.
/// Otherwise, all of the solutions can be written as the form $x \equiv y \pmod z$, using integer $y, z\\ (0 \leq y < z = \text{lcm}(m_i))$.
/// It returns this $(y, z)$.
/// If $n = 0$, returns $(0, 1)$.
pub fn crt(r: &[i64], m: &[i64]) -> (i64, i64) {
assert_eq!(r.len(), m.len());
// Contracts: 0 <= r0 < m0
Expand Down Expand Up @@ -78,6 +120,21 @@ pub fn crt(r: &[i64], m: &[i64]) -> (i64, i64) {
(r0, m0)
}

/// Returns $\sum_{i = 0}^{n - 1} \lfloor \frac{a \times i + b}{m} \rfloor$.
///
/// # Constraints
///
/// - $0 \leq n \leq 10^9$
/// - $1 \leq m \leq 10^9$
/// - $0 \leq a, b \leq m$
///
/// # Panics
///
/// Panics if the above constraints are not satisfied and overflow occurred.
///
/// # Complexity
///
/// - $O(\log(n + m + a + b))$
pub fn floor_sum(n: i64, m: i64, mut a: i64, mut b: i64) -> i64 {
let mut ans = 0;
if a >= m {
Expand Down

0 comments on commit f737533

Please sign in to comment.