Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bb05f6d

Browse filesBrowse files
authored
Add document for convolution (#76)
1 parent 181c1a0 commit bb05f6d
Copy full SHA for bb05f6d

File tree

Expand file treeCollapse file tree

1 file changed

+154
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+154
-0
lines changed

‎src/convolution.rs

Copy file name to clipboardExpand all lines: src/convolution.rs
+154Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
//! Functions that calculate $(+, \times)$ convolution.
2+
//!
3+
//! Given two non-empty sequences $a_0, a_1, \ldots, a_{N - 1}$ and $b_0, b_1, \ldots, b_{M - 1}$, they calculate the sequence $c$ of length $N + M - 1$ defined by
4+
//!
5+
//! \\[
6+
//! c_i = \sum_ {j = 0}^i a_j b_{i - j}
7+
//! \\]
8+
//!
9+
//! # Major changes from the original ACL
10+
//!
11+
//! - Separated the overloaded `convolution` into `convolution<_>` and `convolution_raw<_, _>`.
12+
//! - Renamed `convolution_ll` to `convolution_i64`.
13+
114
macro_rules! modulus {
215
($($name:ident),*) => {
316
$(
@@ -29,6 +42,54 @@ use std::{
2942
fmt,
3043
};
3144

45+
/// Calculates the $(+, \times)$ convolution in $\mathbb{Z}/p\mathbb{Z}$.
46+
///
47+
/// See the [module-level documentation] for more details.
48+
///
49+
/// Returns a empty `Vec` if `a` or `b` is empty.
50+
///
51+
/// # Constraints
52+
///
53+
/// - $2 \leq m \leq 2 \times 10^9$
54+
/// - $m$ is a prime number.
55+
/// - $\exists c \text{ s.t. } 2^c \mid (m - 1), |a| + |b| - 1 \leq 2^c$
56+
///
57+
/// where $m$ is `M::VALUE`.
58+
///
59+
/// # Complexity
60+
///
61+
/// - $O(n \log n + \log m)$ where $n = |a| + |b|$.
62+
///
63+
/// # Example
64+
///
65+
/// ```
66+
/// use ac_library_rs::ModInt1000000007 as Mint;
67+
/// use proconio::{input, source::once::OnceSource};
68+
///
69+
/// input! {
70+
/// from OnceSource::from(
71+
/// "3\n\
72+
/// 1 2 3\n\
73+
/// 3\n\
74+
/// -1 -2 -3\n",
75+
/// ),
76+
/// a: [Mint],
77+
/// b: [Mint],
78+
/// }
79+
///
80+
/// assert_eq!(
81+
/// ac_library_rs::convolution(&a, &b),
82+
/// [
83+
/// Mint::new(-1),
84+
/// Mint::new(-4),
85+
/// Mint::new(-10),
86+
/// Mint::new(-12),
87+
/// Mint::new(-9),
88+
/// ],
89+
/// );
90+
/// ```
91+
///
92+
/// [module-level documentation]: ./index.html
3293
#[allow(clippy::many_single_char_names)]
3394
pub fn convolution<M>(a: &[StaticModInt<M>], b: &[StaticModInt<M>]) -> Vec<StaticModInt<M>>
3495
where
@@ -68,6 +129,61 @@ where
68129
a
69130
}
70131

132+
/// Calculates the $(+, \times)$ convolution in $\mathbb{Z}/p\mathbb{Z}$.
133+
///
134+
/// See the [module-level documentation] for more details.
135+
///
136+
/// Returns a empty `Vec` if `a` or `b` is empty.
137+
///
138+
/// # Constraints
139+
///
140+
/// - $2 \leq m \leq 2 \times 10^9$
141+
/// - $m$ is a prime number.
142+
/// - $\exists c \text{ s.t. } 2^c \mid (m - 1), |a| + |b| - 1 \leq 2^c$
143+
/// - $(0, m] \subseteq$ `T`
144+
///
145+
/// where $m$ is `M::VALUE`.
146+
///
147+
/// # Complexity
148+
///
149+
/// - $O(n \log n + \log m)$ where $n = |a| + |b|$.
150+
///
151+
/// # Panics
152+
///
153+
/// Panics if any element of the result ($\in [0,$ `M::VALUE`$)$) is outside of the range of `T`.
154+
///
155+
/// # Example
156+
///
157+
/// ```
158+
/// use ac_library_rs::{Mod1000000007 as M, Modulus as _};
159+
/// use proconio::{input, source::once::OnceSource};
160+
///
161+
/// const M: i32 = M::VALUE as _;
162+
///
163+
/// input! {
164+
/// from OnceSource::from(
165+
/// "3\n\
166+
/// 1 2 3\n\
167+
/// 3\n\
168+
/// -1 -2 -3\n",
169+
/// ),
170+
/// a: [i32],
171+
/// b: [i32],
172+
/// }
173+
///
174+
/// assert_eq!(
175+
/// ac_library_rs::convolution::convolution_raw::<_, M>(&a, &b),
176+
/// [
177+
/// (-1i32).rem_euclid(M),
178+
/// (-4i32).rem_euclid(M),
179+
/// (-10i32).rem_euclid(M),
180+
/// (-12i32).rem_euclid(M),
181+
/// (-9i32).rem_euclid(M),
182+
/// ],
183+
/// );
184+
/// ```
185+
///
186+
/// [module-level documentation]: ./index.html
71187
pub fn convolution_raw<T, M>(a: &[T], b: &[T]) -> Vec<T>
72188
where
73189
T: RemEuclidU32 + TryFrom<u32> + Clone,
@@ -86,6 +202,44 @@ where
86202
.collect()
87203
}
88204

205+
/// Calculates the $(+, \times)$ convolution in `i64`.
206+
///
207+
/// See the [module-level documentation] for more details.
208+
///
209+
/// Returns a empty `Vec` if `a` or `b` is empty.
210+
///
211+
/// # Constraints
212+
///
213+
/// - $|a| + |b| - 1 \leq 2^{24}$
214+
/// - All elements of the result are inside of the range of `i64`
215+
///
216+
/// # Complexity
217+
///
218+
/// - $O(n \log n)$ where $n = |a| + |b|$.
219+
///
220+
/// # Example
221+
///
222+
/// ```
223+
/// use proconio::{input, source::once::OnceSource};
224+
///
225+
/// input! {
226+
/// from OnceSource::from(
227+
/// "3\n\
228+
/// 1 2 3\n\
229+
/// 3\n\
230+
/// -1 -2 -3\n",
231+
/// ),
232+
/// a: [i64],
233+
/// b: [i64],
234+
/// }
235+
///
236+
/// assert_eq!(
237+
/// ac_library_rs::convolution_i64(&a, &b),
238+
/// [-1, -4, -10, -12, -9],
239+
/// );
240+
/// ```
241+
///
242+
/// [module-level documentation]: ./index.html
89243
#[allow(clippy::many_single_char_names)]
90244
pub fn convolution_i64(a: &[i64], b: &[i64]) -> Vec<i64> {
91245
const M1: u64 = 754_974_721; // 2^24

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.