1
+ //! Number-theoretic algorithms.
2
+
1
3
use crate :: internal_math;
2
4
3
5
use std:: mem:: swap;
4
6
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)$
21
+ ///
22
+ /// # Example
23
+ ///
24
+ /// ```
25
+ /// use ac_library_rs::math;
26
+ ///
27
+ /// assert_eq!(math::pow_mod(2, 10000, 7), 2);
28
+ /// ```
5
29
#[ allow( clippy:: many_single_char_names) ]
6
30
pub fn pow_mod ( x : i64 , mut n : i64 , m : u32 ) -> u32 {
7
31
assert ! ( 0 <= n && 1 <= m && m <= 2u32 . pow( 31 ) ) ;
@@ -21,13 +45,73 @@ pub fn pow_mod(x: i64, mut n: i64, m: u32) -> u32 {
21
45
r
22
46
}
23
47
48
+ /// Returns an integer $y \in [0, m)$ such that $xy \equiv 1 \pmod m$.
49
+ ///
50
+ /// # Constraints
51
+ ///
52
+ /// - $\gcd(x, m) = 1$
53
+ /// - $1 \leq m$
54
+ ///
55
+ /// # Panics
56
+ ///
57
+ /// Panics if the above constraints are not satisfied.
58
+ ///
59
+ /// # Complexity
60
+ ///
61
+ /// - $O(\log m)$
62
+ ///
63
+ /// # Example
64
+ ///
65
+ /// ```
66
+ /// use ac_library_rs::math;
67
+ ///
68
+ /// assert_eq!(math::inv_mod(3, 7), 5);
69
+ /// ```
24
70
pub fn inv_mod ( x : i64 , m : i64 ) -> i64 {
25
71
assert ! ( 1 <= m) ;
26
72
let z = internal_math:: inv_gcd ( x, m) ;
27
73
assert ! ( z. 0 == 1 ) ;
28
74
z. 1
29
75
}
30
76
77
+ /// Performs CRT (Chinese Remainder Theorem).
78
+ ///
79
+ /// Given two sequences $r, m$ of length $n$, this function solves the modular equation system
80
+ ///
81
+ /// \\[
82
+ /// x \equiv r_i \pmod{m_i}, \forall i \in \\{0, 1, \cdots, n - 1\\}
83
+ /// \\]
84
+ ///
85
+ /// If there is no solution, it returns $(0, 0)$.
86
+ ///
87
+ /// 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))$.
88
+ /// It returns this $(y, z)$.
89
+ ///
90
+ /// If $n = 0$, it returns $(0, 1)$.
91
+ ///
92
+ /// # Constraints
93
+ ///
94
+ /// - $|r| = |m|$
95
+ /// - $1 \leq m_{\forall i}$
96
+ /// - $\text{lcm}(m)$ is in `i64`
97
+ ///
98
+ /// # Panics
99
+ ///
100
+ /// Panics if the above constraints are not satisfied.
101
+ ///
102
+ /// # Complexity
103
+ ///
104
+ /// - $O(n \log \text{lcm}(m))$
105
+ ///
106
+ /// # Example
107
+ ///
108
+ /// ```
109
+ /// use ac_library_rs::math;
110
+ ///
111
+ /// let r = [2, 3, 2];
112
+ /// let m = [3, 5, 7];
113
+ /// assert_eq!(math::crt(&r, &m), (23, 105));
114
+ /// ```
31
115
pub fn crt ( r : & [ i64 ] , m : & [ i64 ] ) -> ( i64 , i64 ) {
32
116
assert_eq ! ( r. len( ) , m. len( ) ) ;
33
117
// Contracts: 0 <= r0 < m0
@@ -78,6 +162,29 @@ pub fn crt(r: &[i64], m: &[i64]) -> (i64, i64) {
78
162
( r0, m0)
79
163
}
80
164
165
+ /// Returns $\sum_{i = 0}^{n - 1} \lfloor \frac{a \times i + b}{m} \rfloor$.
166
+ ///
167
+ /// # Constraints
168
+ ///
169
+ /// - $0 \leq n \leq 10^9$
170
+ /// - $1 \leq m \leq 10^9$
171
+ /// - $0 \leq a, b \leq m$
172
+ ///
173
+ /// # Panics
174
+ ///
175
+ /// Panics if the above constraints are not satisfied and overflow or division by zero occurred.
176
+ ///
177
+ /// # Complexity
178
+ ///
179
+ /// - $O(\log(n + m + a + b))$
180
+ ///
181
+ /// # Example
182
+ ///
183
+ /// ```
184
+ /// use ac_library_rs::math;
185
+ ///
186
+ /// assert_eq!(math::floor_sum(6, 5, 4, 3), 13);
187
+ /// ```
81
188
pub fn floor_sum ( n : i64 , m : i64 , mut a : i64 , mut b : i64 ) -> i64 {
82
189
let mut ans = 0 ;
83
190
if a >= m {
0 commit comments