1+ //! Number-theoretic algorithms.
2+
13use crate :: internal_math;
24
35use std:: mem:: swap;
46
7+ /// Returns $x^n \bmod m$.
8+ ///
9+ /// # Constraints
10+ ///
11+ /// - $0 \leq n$
12+ /// - $1 \leq m$
13+ ///
14+ /// # Panics
15+ ///
16+ /// Panics if the above constraints are not satisfied.
17+ ///
18+ /// # Complexity
19+ ///
20+ /// - $O(\log n)$
521#[ allow( clippy:: many_single_char_names) ]
622pub fn pow_mod ( x : i64 , mut n : i64 , m : u32 ) -> u32 {
723 assert ! ( 0 <= n && 1 <= m && m <= 2u32 . pow( 31 ) ) ;
@@ -21,13 +37,39 @@ pub fn pow_mod(x: i64, mut n: i64, m: u32) -> u32 {
2137 r
2238}
2339
40+ /// Returns an integer $y$ such that $0 \leq y < m$ and $xy \equiv 1 \pmod m$.
41+ ///
42+ /// # Constraints
43+ ///
44+ /// - $\gcd(x, m) = 1$
45+ /// - $1 \leq m$
46+ ///
47+ /// # Panics
48+ ///
49+ /// Panics if the above constraints are not satisfied.
50+ ///
51+ /// # Complexity
52+ ///
53+ /// - $O(\log m)$
2454pub fn inv_mod ( x : i64 , m : i64 ) -> i64 {
2555 assert ! ( 1 <= m) ;
2656 let z = internal_math:: inv_gcd ( x, m) ;
2757 assert ! ( z. 0 == 1 ) ;
2858 z. 1
2959}
3060
61+ /// CRT.
62+ ///
63+ /// Given two sequences $r, m$ of length $n$, solves the modular equation system
64+ ///
65+ /// \\[
66+ /// x \equiv r_i \pmod m_i, \forall i \in \\{0, 1, \cdots, n - 1\\}
67+ /// \\]
68+ ///
69+ /// If there is no solution, returns $(0, 0)$.
70+ /// 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))$.
71+ /// It returns this $(y, z)$.
72+ /// If $n = 0$, returns $(0, 1)$.
3173pub fn crt ( r : & [ i64 ] , m : & [ i64 ] ) -> ( i64 , i64 ) {
3274 assert_eq ! ( r. len( ) , m. len( ) ) ;
3375 // Contracts: 0 <= r0 < m0
@@ -78,6 +120,21 @@ pub fn crt(r: &[i64], m: &[i64]) -> (i64, i64) {
78120 ( r0, m0)
79121}
80122
123+ /// Returns $\sum_{i = 0}^{n - 1} \lfloor \frac{a \times i + b}{m} \rfloor$.
124+ ///
125+ /// # Constraints
126+ ///
127+ /// - $0 \leq n \leq 10^9$
128+ /// - $1 \leq m \leq 10^9$
129+ /// - $0 \leq a, b \leq m$
130+ ///
131+ /// # Panics
132+ ///
133+ /// Panics if the above constraints are not satisfied and overflow occurred.
134+ ///
135+ /// # Complexity
136+ ///
137+ /// - $O(\log(n + m + a + b))$
81138pub fn floor_sum ( n : i64 , m : i64 , mut a : i64 , mut b : i64 ) -> i64 {
82139 let mut ans = 0 ;
83140 if a >= m {
0 commit comments