1
+ //! Functions that calculate $(+, \times)$ convolution.
2
+ //!
3
+ //! Given two arrays $a_0, a_1, \ldots, a_{N - 1}$ and $a_0, a_1, \ldots, a_{M - 1}$, They calculate the array $c$ of length $N + M - 1$, defined by
4
+ //!
5
+ //! \\[
6
+ //! c_i = \sum_ {j = 0}^i a_j b_{i - j}
7
+ //! \\]
8
+
1
9
macro_rules! modulus {
2
10
( $( $name: ident) ,* ) => {
3
11
$(
@@ -29,6 +37,50 @@ use std::{
29
37
fmt,
30
38
} ;
31
39
40
+ /// Calculates the $(+, \times)$ convolution in $\mathbb{Z}/p\mathbb{Z}$.
41
+ ///
42
+ /// Returns a empty `Vec` if `a` or `b` is empty.
43
+ ///
44
+ /// # Constraints
45
+ ///
46
+ /// - $2 \leq m \leq 2 \times 10^9$
47
+ /// - $m$ is a prime number.
48
+ /// - $\exists c \text{ s.t. } 2^c \mid (m - 1), |a| + |b| - 1 \leq 2^c$
49
+ ///
50
+ /// where $m$ is `M::VALUE`.
51
+ ///
52
+ /// # Complexity
53
+ ///
54
+ /// - $O(n \log n + \log m)$ where $n = |a| + |b|$.
55
+ ///
56
+ /// # Example
57
+ ///
58
+ /// ```
59
+ /// use ac_library_rs::ModInt1000000007 as Mint;
60
+ /// use proconio::{input, source::once::OnceSource};
61
+ ///
62
+ /// input! {
63
+ /// from OnceSource::from(
64
+ /// "3\n\
65
+ /// 1 2 3\n\
66
+ /// 3\n\
67
+ /// -1 -2 -3\n",
68
+ /// ),
69
+ /// a: [Mint],
70
+ /// b: [Mint],
71
+ /// }
72
+ ///
73
+ /// assert_eq!(
74
+ /// ac_library_rs::convolution(&a, &b),
75
+ /// [
76
+ /// Mint::new(-1),
77
+ /// Mint::new(-4),
78
+ /// Mint::new(-10),
79
+ /// Mint::new(-12),
80
+ /// Mint::new(-9),
81
+ /// ],
82
+ /// );
83
+ /// ```
32
84
#[ allow( clippy:: many_single_char_names) ]
33
85
pub fn convolution < M > ( a : & [ StaticModInt < M > ] , b : & [ StaticModInt < M > ] ) -> Vec < StaticModInt < M > >
34
86
where
@@ -68,6 +120,52 @@ where
68
120
a
69
121
}
70
122
123
+ /// Calculates the $(+, \times)$ convolution in $\mathbb{Z}/p\mathbb{Z}$.
124
+ ///
125
+ /// Returns a empty `Vec` if `a` or `b` is empty.
126
+ ///
127
+ /// # Constraints
128
+ ///
129
+ /// - $2 \leq m \leq 2 \times 10^9$
130
+ /// - $m$ is a prime number.
131
+ /// - $\exists c \text{ s.t. } 2^c \mid (m - 1), |a| + |b| - 1 \leq 2^c$
132
+ ///
133
+ /// where $m$ is `M::VALUE`.
134
+ ///
135
+ /// # Complexity
136
+ ///
137
+ /// - $O(n \log n + \log m)$ where $n = |a| + |b|$.
138
+ ///
139
+ /// # Example
140
+ ///
141
+ /// ```
142
+ /// use ac_library_rs::{Mod1000000007 as M, Modulus as _};
143
+ /// use proconio::{input, source::once::OnceSource};
144
+ ///
145
+ /// const M: u32 = M::VALUE;
146
+ ///
147
+ /// input! {
148
+ /// from OnceSource::from(
149
+ /// "3\n\
150
+ /// 1 2 3\n\
151
+ /// 3\n\
152
+ /// -1 -2 -3\n",
153
+ /// ),
154
+ /// a: [i32],
155
+ /// b: [i32],
156
+ /// }
157
+ ///
158
+ /// assert_eq!(
159
+ /// ac_library_rs::convolution::convolution_raw::<_, M>(&a, &b),
160
+ /// [
161
+ /// (-1i32).rem_euclid(M as i32),
162
+ /// (-4i32).rem_euclid(M as i32),
163
+ /// (-10i32).rem_euclid(M as i32),
164
+ /// (-12i32).rem_euclid(M as i32),
165
+ /// (-9i32).rem_euclid(M as i32),
166
+ /// ],
167
+ /// );
168
+ /// ```
71
169
pub fn convolution_raw < T , M > ( a : & [ T ] , b : & [ T ] ) -> Vec < T >
72
170
where
73
171
T : RemEuclidU32 + TryFrom < u32 > + Clone ,
@@ -86,6 +184,40 @@ where
86
184
. collect ( )
87
185
}
88
186
187
+ /// Calculates the $(+, \times)$ convolution in `i64`.
188
+ ///
189
+ /// Returns a empty `Vec` if `a` or `b` is empty.
190
+ ///
191
+ /// # Constraints
192
+ ///
193
+ /// - $|a| + |b| - 1 \leq 2^{24}$
194
+ /// - All elements of the result are inside of the range of `i64`
195
+ ///
196
+ /// # Complexity
197
+ ///
198
+ /// - $O(n \log n)$ where $n = |a| + |b|$.
199
+ ///
200
+ /// # Example
201
+ ///
202
+ /// ```
203
+ /// use proconio::{input, source::once::OnceSource};
204
+ ///
205
+ /// input! {
206
+ /// from OnceSource::from(
207
+ /// "3\n\
208
+ /// 1 2 3\n\
209
+ /// 3\n\
210
+ /// -1 -2 -3\n",
211
+ /// ),
212
+ /// a: [i64],
213
+ /// b: [i64],
214
+ /// }
215
+ ///
216
+ /// assert_eq!(
217
+ /// ac_library_rs::convolution_i64(&a, &b),
218
+ /// [-1, -4, -10, -12, -9],
219
+ /// );
220
+ /// ```
89
221
#[ allow( clippy:: many_single_char_names) ]
90
222
pub fn convolution_i64 ( a : & [ i64 ] , b : & [ i64 ] ) -> Vec < i64 > {
91
223
const M1 : u64 = 754_974_721 ; // 2^24
0 commit comments