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)$
5
21
#[ allow( clippy:: many_single_char_names) ]
6
22
pub fn pow_mod ( x : i64 , mut n : i64 , m : u32 ) -> u32 {
7
23
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 {
21
37
r
22
38
}
23
39
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)$
24
54
pub fn inv_mod ( x : i64 , m : i64 ) -> i64 {
25
55
assert ! ( 1 <= m) ;
26
56
let z = internal_math:: inv_gcd ( x, m) ;
27
57
assert ! ( z. 0 == 1 ) ;
28
58
z. 1
29
59
}
30
60
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)$.
31
73
pub fn crt ( r : & [ i64 ] , m : & [ i64 ] ) -> ( i64 , i64 ) {
32
74
assert_eq ! ( r. len( ) , m. len( ) ) ;
33
75
// Contracts: 0 <= r0 < m0
@@ -78,6 +120,21 @@ pub fn crt(r: &[i64], m: &[i64]) -> (i64, i64) {
78
120
( r0, m0)
79
121
}
80
122
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))$
81
138
pub fn floor_sum ( n : i64 , m : i64 , mut a : i64 , mut b : i64 ) -> i64 {
82
139
let mut ans = 0 ;
83
140
if a >= m {
0 commit comments