#[repr(transparent)]pub struct MInt<M>where
M: MIntBase,{
x: M::Inner,
_marker: PhantomData<fn() -> M>,
}Fields§
§x: M::Inner§_marker: PhantomData<fn() -> M>Implementations§
Source§impl<M> MInt<M>where
M: MIntConvert<u32>,
impl<M> MInt<M>where
M: MIntConvert<u32>,
Sourcepub fn sqrt(self) -> Option<Self>
pub fn sqrt(self) -> Option<Self>
Examples found in repository?
More examples
crates/library_checker/src/number_theory/sqrt_mod.rs (line 12)
6pub fn sqrt_mod(reader: impl Read, mut writer: impl Write) {
7 let s = read_all_unchecked(reader);
8 let mut scanner = Scanner::new(&s);
9 scan!(scanner, q, yp: [(u32, u32)]);
10 for (y, p) in yp.take(q) {
11 DynMIntU32::set_mod(p);
12 if let Some(x) = DynMIntU32::from(y).sqrt() {
13 writeln!(writer, "{}", x).ok();
14 } else {
15 writeln!(writer, "-1").ok();
16 }
17 }
18}Source§impl<M> MInt<M>where
M: MIntConvert,
impl<M> MInt<M>where
M: MIntConvert,
Sourcepub fn new(x: M::Inner) -> Self
pub fn new(x: M::Inner) -> Self
Examples found in repository?
crates/library_checker/src/number_theory/sum_of_totient_function.rs (line 19)
12pub fn sum_of_totient_function(reader: impl Read, mut writer: impl Write) {
13 let s = read_all_unchecked(reader);
14 let mut scanner = Scanner::new(&s);
15 scan!(scanner, n: u64);
16 let mut s = 1;
17 let mut pp = 0;
18 let mut pc = 0;
19 let inv2 = M::new(2).inv();
20 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
21 .map(|[x, y]| [x - M::one(), y - M::one()])
22 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
23 .map(|[x, y]| y - x)
24 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
25 if pp != p || pc > c {
26 pp = p;
27 pc = 1;
28 s = p - 1;
29 }
30 while pc < c {
31 pc += 1;
32 s *= p;
33 }
34 M::from(s)
35 });
36 writeln!(writer, "{}", qa[n]).ok();
37}More examples
crates/competitive/src/math/number_theoretic_transform.rs (line 427)
426 fn inverse_transform(f: Self::F, len: usize) -> Self::T {
427 let t1 = MInt::<N2>::new(N1::get_mod()).inv();
428 let m1 = MInt::<M>::from(N1::get_mod());
429 let m1_3 = MInt::<N3>::new(N1::get_mod());
430 let t2 = (m1_3 * MInt::<N3>::new(N2::get_mod())).inv();
431 let m2 = m1 * MInt::<M>::from(N2::get_mod());
432 Convolve::<N1>::inverse_transform(f.0, len)
433 .into_iter()
434 .zip(Convolve::<N2>::inverse_transform(f.1, len))
435 .zip(Convolve::<N3>::inverse_transform(f.2, len))
436 .map(|((c1, c2), c3)| {
437 let d1 = c1.inner();
438 let d2 = ((c2 - MInt::<N2>::from(d1)) * t1).inner();
439 let x = MInt::<N3>::new(d1) + MInt::<N3>::new(d2) * m1_3;
440 let d3 = ((c3 - x) * t2).inner();
441 MInt::<M>::from(d1) + MInt::<M>::from(d2) * m1 + MInt::<M>::from(d3) * m2
442 })
443 .collect()
444 }
445 fn multiply(f: &mut Self::F, g: &Self::F) {
446 assert_eq!(f.0.len(), g.0.len());
447 assert_eq!(f.1.len(), g.1.len());
448 assert_eq!(f.2.len(), g.2.len());
449 for (f, g) in f.0.iter_mut().zip(g.0.iter()) {
450 *f *= *g;
451 }
452 for (f, g) in f.1.iter_mut().zip(g.1.iter()) {
453 *f *= *g;
454 }
455 for (f, g) in f.2.iter_mut().zip(g.2.iter()) {
456 *f *= *g;
457 }
458 }
459 fn convolve(a: Self::T, b: Self::T) -> Self::T {
460 if Self::length(&a).max(Self::length(&b)) <= 300 {
461 return convolve_karatsuba(&a, &b);
462 }
463 if Self::length(&a).min(Self::length(&b)) <= 60 {
464 return convolve_naive(&a, &b);
465 }
466 let len = (Self::length(&a) + Self::length(&b)).saturating_sub(1);
467 let mut a = Self::transform(a, len);
468 let b = Self::transform(b, len);
469 Self::multiply(&mut a, &b);
470 Self::inverse_transform(a, len)
471 }
472}
473
474impl<N1, N2, N3> ConvolveSteps for Convolve<(u64, (N1, N2, N3))>
475where
476 N1: Montgomery32NttModulus,
477 N2: Montgomery32NttModulus,
478 N3: Montgomery32NttModulus,
479{
480 type T = Vec<u64>;
481 type F = (MVec<N1>, MVec<N2>, MVec<N3>);
482
483 fn length(t: &Self::T) -> usize {
484 t.len()
485 }
486
487 fn transform(t: Self::T, len: usize) -> Self::F {
488 let npot = len.max(1).next_power_of_two();
489 let mut f = (
490 MVec::<N1>::with_capacity(npot),
491 MVec::<N2>::with_capacity(npot),
492 MVec::<N3>::with_capacity(npot),
493 );
494 for t in t {
495 f.0.push(t.into());
496 f.1.push(t.into());
497 f.2.push(t.into());
498 }
499 f.0.resize_with(npot, Zero::zero);
500 f.1.resize_with(npot, Zero::zero);
501 f.2.resize_with(npot, Zero::zero);
502 ntt(&mut f.0);
503 ntt(&mut f.1);
504 ntt(&mut f.2);
505 f
506 }
507
508 fn inverse_transform(f: Self::F, len: usize) -> Self::T {
509 let t1 = MInt::<N2>::new(N1::get_mod()).inv();
510 let m1 = N1::get_mod() as u64;
511 let m1_3 = MInt::<N3>::new(N1::get_mod());
512 let t2 = (m1_3 * MInt::<N3>::new(N2::get_mod())).inv();
513 let m2 = m1 * N2::get_mod() as u64;
514 Convolve::<N1>::inverse_transform(f.0, len)
515 .into_iter()
516 .zip(Convolve::<N2>::inverse_transform(f.1, len))
517 .zip(Convolve::<N3>::inverse_transform(f.2, len))
518 .map(|((c1, c2), c3)| {
519 let d1 = c1.inner();
520 let d2 = ((c2 - MInt::<N2>::from(d1)) * t1).inner();
521 let x = MInt::<N3>::new(d1) + MInt::<N3>::new(d2) * m1_3;
522 let d3 = ((c3 - x) * t2).inner();
523 d1 as u64 + d2 as u64 * m1 + d3 as u64 * m2
524 })
525 .collect()
526 }
527
528 fn multiply(f: &mut Self::F, g: &Self::F) {
529 assert_eq!(f.0.len(), g.0.len());
530 assert_eq!(f.1.len(), g.1.len());
531 assert_eq!(f.2.len(), g.2.len());
532 for (f, g) in f.0.iter_mut().zip(g.0.iter()) {
533 *f *= *g;
534 }
535 for (f, g) in f.1.iter_mut().zip(g.1.iter()) {
536 *f *= *g;
537 }
538 for (f, g) in f.2.iter_mut().zip(g.2.iter()) {
539 *f *= *g;
540 }
541 }
542
543 fn convolve(a: Self::T, b: Self::T) -> Self::T {
544 if Self::length(&a).max(Self::length(&b)) <= 300 {
545 return convolve_karatsuba(&a, &b);
546 }
547 if Self::length(&a).min(Self::length(&b)) <= 60 {
548 return convolve_naive(&a, &b);
549 }
550 let len = (Self::length(&a) + Self::length(&b)).saturating_sub(1);
551 let mut a = Self::transform(a, len);
552 let b = Self::transform(b, len);
553 Self::multiply(&mut a, &b);
554 Self::inverse_transform(a, len)
555 }
556}
557
558pub trait NttReuse: ConvolveSteps {
559 const MULTIPLE: bool = true;
560
561 /// F(a) → F(a + [0] * a.len())
562 fn ntt_doubling(f: Self::F) -> Self::F;
563
564 /// F(a(x)), F(b(x)) → even(F(a(x) * b(-x)))
565 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F;
566
567 /// F(a(x)), F(b(x)) → odd(F(a(x) * b(-x)))
568 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F;
569}
570
571thread_local!(
572 static BIT_REVERSE: UnsafeCell<Vec<Vec<usize>>> = const { UnsafeCell::new(vec![]) };
573);
574
575impl<M> NttReuse for Convolve<M>
576where
577 M: Montgomery32NttModulus,
578{
579 const MULTIPLE: bool = false;
580
581 fn ntt_doubling(mut f: Self::F) -> Self::F {
582 let n = f.len();
583 let k = n.trailing_zeros() as usize;
584 let mut a = Self::inverse_transform(f.clone(), n);
585 let mut rot = MInt::<M>::one();
586 let zeta = MInt::<M>::new_unchecked(M::INFO.root[k + 1]);
587 for a in a.iter_mut() {
588 *a *= rot;
589 rot *= zeta;
590 }
591 f.extend(Self::transform(a, n));
592 f
593 }
594
595 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
596 assert_eq!(f.len(), g.len());
597 assert!(f.len().is_power_of_two());
598 assert!(f.len() >= 2);
599 let inv2 = MInt::<M>::from(2).inv();
600 let n = f.len() / 2;
601 (0..n)
602 .map(|i| (f[i << 1] * g[i << 1 | 1] + f[i << 1 | 1] * g[i << 1]) * inv2)
603 .collect()
604 }
605
606 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
607 assert_eq!(f.len(), g.len());
608 assert!(f.len().is_power_of_two());
609 assert!(f.len() >= 2);
610 let mut inv2 = MInt::<M>::from(2).inv();
611 let n = f.len() / 2;
612 let k = f.len().trailing_zeros() as usize;
613 let mut h = vec![MInt::<M>::zero(); n];
614 let w = MInt::<M>::new_unchecked(M::INFO.inv_root[k]);
615 BIT_REVERSE.with(|br| {
616 let br = unsafe { &mut *br.get() };
617 if br.len() < k {
618 br.resize_with(k, Default::default);
619 }
620 let k = k - 1;
621 if br[k].is_empty() {
622 let mut v = vec![0; 1 << k];
623 for i in 0..1 << k {
624 v[i] = (v[i >> 1] >> 1) | ((i & 1) << (k.saturating_sub(1)));
625 }
626 br[k] = v;
627 }
628 for &i in &br[k] {
629 h[i] = (f[i << 1] * g[i << 1 | 1] - f[i << 1 | 1] * g[i << 1]) * inv2;
630 inv2 *= w;
631 }
632 });
633 h
634 }
635}
636
637impl<M, N1, N2, N3> NttReuse for Convolve<(M, (N1, N2, N3))>
638where
639 M: MIntConvert + MIntConvert<u32>,
640 N1: Montgomery32NttModulus,
641 N2: Montgomery32NttModulus,
642 N3: Montgomery32NttModulus,
643{
644 fn ntt_doubling(f: Self::F) -> Self::F {
645 (
646 Convolve::<N1>::ntt_doubling(f.0),
647 Convolve::<N2>::ntt_doubling(f.1),
648 Convolve::<N3>::ntt_doubling(f.2),
649 )
650 }
651
652 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
653 fn even_mul_normal_neg_corrected<M>(f: &[MInt<M>], g: &[MInt<M>], m: u32) -> Vec<MInt<M>>
654 where
655 M: Montgomery32NttModulus,
656 {
657 let n = f.len();
658 assert_eq!(f.len(), g.len());
659 assert!(f.len().is_power_of_two());
660 assert!(f.len() >= 2);
661 let inv2 = MInt::<M>::from(2).inv();
662 let u = MInt::<M>::new(m) * MInt::<M>::from(n as u32);
663 let n = f.len() / 2;
664 (0..n)
665 .map(|i| {
666 (f[i << 1]
667 * if i == 0 {
668 g[i << 1 | 1] + u
669 } else {
670 g[i << 1 | 1]
671 }
672 + f[i << 1 | 1] * g[i << 1])
673 * inv2
674 })
675 .collect()
676 }
677
678 let m = M::mod_into();
679 (
680 even_mul_normal_neg_corrected(&f.0, &g.0, m),
681 even_mul_normal_neg_corrected(&f.1, &g.1, m),
682 even_mul_normal_neg_corrected(&f.2, &g.2, m),
683 )
684 }
685
686 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
687 fn odd_mul_normal_neg_corrected<M>(f: &[MInt<M>], g: &[MInt<M>], m: u32) -> Vec<MInt<M>>
688 where
689 M: Montgomery32NttModulus,
690 {
691 assert_eq!(f.len(), g.len());
692 assert!(f.len().is_power_of_two());
693 assert!(f.len() >= 2);
694 let mut inv2 = MInt::<M>::from(2).inv();
695 let u = MInt::<M>::new(m) * MInt::<M>::from(f.len() as u32);
696 let n = f.len() / 2;
697 let k = f.len().trailing_zeros() as usize;
698 let mut h = vec![MInt::<M>::zero(); n];
699 let w = MInt::<M>::new_unchecked(M::INFO.inv_root[k]);
700 BIT_REVERSE.with(|br| {
701 let br = unsafe { &mut *br.get() };
702 if br.len() < k {
703 br.resize_with(k, Default::default);
704 }
705 let k = k - 1;
706 if br[k].is_empty() {
707 let mut v = vec![0; 1 << k];
708 for i in 0..1 << k {
709 v[i] = (v[i >> 1] >> 1) | ((i & 1) << (k.saturating_sub(1)));
710 }
711 br[k] = v;
712 }
713 for &i in &br[k] {
714 h[i] = (f[i << 1]
715 * if i == 0 {
716 g[i << 1 | 1] + u
717 } else {
718 g[i << 1 | 1]
719 }
720 - f[i << 1 | 1] * g[i << 1])
721 * inv2;
722 inv2 *= w;
723 }
724 });
725 h
726 }Source§impl<M> MInt<M>where
M: MIntBase,
impl<M> MInt<M>where
M: MIntBase,
Sourcepub const fn new_unchecked(x: M::Inner) -> Self
pub const fn new_unchecked(x: M::Inner) -> Self
Examples found in repository?
crates/competitive/src/num/mint/mint_base.rs (line 60)
59 pub fn new(x: M::Inner) -> Self {
60 Self::new_unchecked(<M as MIntConvert<M::Inner>>::from(x))
61 }
62}
63impl<M> MInt<M>
64where
65 M: MIntBase,
66{
67 #[inline]
68 pub const fn new_unchecked(x: M::Inner) -> Self {
69 Self {
70 x,
71 _marker: PhantomData,
72 }
73 }
74 #[inline]
75 pub fn get_mod() -> M::Inner {
76 M::get_mod()
77 }
78 #[inline]
79 pub fn pow(self, y: usize) -> Self {
80 Self::new_unchecked(M::mod_pow(self.x, y))
81 }
82 #[inline]
83 pub fn inv(self) -> Self {
84 Self::new_unchecked(M::mod_inv(self.x))
85 }
86 #[inline]
87 pub fn inner(self) -> M::Inner {
88 M::mod_inner(self.x)
89 }
90}
91
92impl<M> Clone for MInt<M>
93where
94 M: MIntBase,
95{
96 #[inline]
97 fn clone(&self) -> Self {
98 *self
99 }
100}
101impl<M> Copy for MInt<M> where M: MIntBase {}
102impl<M> Debug for MInt<M>
103where
104 M: MIntBase,
105{
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 Debug::fmt(&self.inner(), f)
108 }
109}
110impl<M> Default for MInt<M>
111where
112 M: MIntBase,
113{
114 #[inline]
115 fn default() -> Self {
116 <Self as Zero>::zero()
117 }
118}
119impl<M> PartialEq for MInt<M>
120where
121 M: MIntBase,
122{
123 #[inline]
124 fn eq(&self, other: &Self) -> bool {
125 PartialEq::eq(&self.x, &other.x)
126 }
127}
128impl<M> Eq for MInt<M> where M: MIntBase {}
129impl<M> Hash for MInt<M>
130where
131 M: MIntBase,
132{
133 #[inline]
134 fn hash<H: Hasher>(&self, state: &mut H) {
135 Hash::hash(&self.x, state)
136 }
137}
138macro_rules! impl_mint_from {
139 ($($t:ty),*) => {
140 $(impl<M> From<$t> for MInt<M>
141 where
142 M: MIntConvert<$t>,
143 {
144 #[inline]
145 fn from(x: $t) -> Self {
146 Self::new_unchecked(<M as MIntConvert<$t>>::from(x))
147 }
148 }
149 impl<M> From<MInt<M>> for $t
150 where
151 M: MIntConvert<$t>,
152 {
153 #[inline]
154 fn from(x: MInt<M>) -> $t {
155 <M as MIntConvert<$t>>::into(x.x)
156 }
157 })*
158 };
159}
160impl_mint_from!(
161 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
162);
163impl<M> Zero for MInt<M>
164where
165 M: MIntBase,
166{
167 #[inline]
168 fn zero() -> Self {
169 Self::new_unchecked(M::mod_zero())
170 }
171}
172impl<M> One for MInt<M>
173where
174 M: MIntBase,
175{
176 #[inline]
177 fn one() -> Self {
178 Self::new_unchecked(M::mod_one())
179 }
180}
181
182impl<M> Add for MInt<M>
183where
184 M: MIntBase,
185{
186 type Output = Self;
187 #[inline]
188 fn add(self, rhs: Self) -> Self::Output {
189 Self::new_unchecked(M::mod_add(self.x, rhs.x))
190 }
191}
192impl<M> Sub for MInt<M>
193where
194 M: MIntBase,
195{
196 type Output = Self;
197 #[inline]
198 fn sub(self, rhs: Self) -> Self::Output {
199 Self::new_unchecked(M::mod_sub(self.x, rhs.x))
200 }
201}
202impl<M> Mul for MInt<M>
203where
204 M: MIntBase,
205{
206 type Output = Self;
207 #[inline]
208 fn mul(self, rhs: Self) -> Self::Output {
209 Self::new_unchecked(M::mod_mul(self.x, rhs.x))
210 }
211}
212impl<M> Div for MInt<M>
213where
214 M: MIntBase,
215{
216 type Output = Self;
217 #[inline]
218 fn div(self, rhs: Self) -> Self::Output {
219 Self::new_unchecked(M::mod_div(self.x, rhs.x))
220 }
221}
222impl<M> Neg for MInt<M>
223where
224 M: MIntBase,
225{
226 type Output = Self;
227 #[inline]
228 fn neg(self) -> Self::Output {
229 Self::new_unchecked(M::mod_neg(self.x))
230 }
231}
232impl<M> Sum for MInt<M>
233where
234 M: MIntBase,
235{
236 #[inline]
237 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
238 iter.fold(<Self as Zero>::zero(), Add::add)
239 }
240}
241impl<M> Product for MInt<M>
242where
243 M: MIntBase,
244{
245 #[inline]
246 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
247 iter.fold(<Self as One>::one(), Mul::mul)
248 }
249}
250impl<'a, M: 'a> Sum<&'a MInt<M>> for MInt<M>
251where
252 M: MIntBase,
253{
254 #[inline]
255 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
256 iter.fold(<Self as Zero>::zero(), Add::add)
257 }
258}
259impl<'a, M: 'a> Product<&'a MInt<M>> for MInt<M>
260where
261 M: MIntBase,
262{
263 #[inline]
264 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
265 iter.fold(<Self as One>::one(), Mul::mul)
266 }
267}
268impl<M> Display for MInt<M>
269where
270 M: MIntBase<Inner: Display>,
271{
272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
273 write!(f, "{}", self.inner())
274 }
275}
276impl<M> FromStr for MInt<M>
277where
278 M: MIntConvert + MIntBase<Inner: FromStr>,
279{
280 type Err = <M::Inner as FromStr>::Err;
281 #[inline]
282 fn from_str(s: &str) -> Result<Self, Self::Err> {
283 s.parse::<M::Inner>().map(Self::new)
284 }
285}
286impl<M> IterScan for MInt<M>
287where
288 M: MIntConvert + MIntBase<Inner: FromStr>,
289{
290 type Output = Self;
291 #[inline]
292 fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
293 iter.next()?.parse::<MInt<M>>().ok()
294 }
295}
296impl<M> SerdeByteStr for MInt<M>
297where
298 M: MIntBase<Inner: SerdeByteStr>,
299{
300 fn serialize(&self, buf: &mut Vec<u8>) {
301 self.inner().serialize(buf)
302 }
303
304 fn deserialize<I>(iter: &mut I) -> Self
305 where
306 I: Iterator<Item = u8>,
307 {
308 Self::new_unchecked(M::Inner::deserialize(iter))
309 }More examples
crates/competitive/src/math/number_theoretic_transform.rs (line 586)
581 fn ntt_doubling(mut f: Self::F) -> Self::F {
582 let n = f.len();
583 let k = n.trailing_zeros() as usize;
584 let mut a = Self::inverse_transform(f.clone(), n);
585 let mut rot = MInt::<M>::one();
586 let zeta = MInt::<M>::new_unchecked(M::INFO.root[k + 1]);
587 for a in a.iter_mut() {
588 *a *= rot;
589 rot *= zeta;
590 }
591 f.extend(Self::transform(a, n));
592 f
593 }
594
595 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
596 assert_eq!(f.len(), g.len());
597 assert!(f.len().is_power_of_two());
598 assert!(f.len() >= 2);
599 let inv2 = MInt::<M>::from(2).inv();
600 let n = f.len() / 2;
601 (0..n)
602 .map(|i| (f[i << 1] * g[i << 1 | 1] + f[i << 1 | 1] * g[i << 1]) * inv2)
603 .collect()
604 }
605
606 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
607 assert_eq!(f.len(), g.len());
608 assert!(f.len().is_power_of_two());
609 assert!(f.len() >= 2);
610 let mut inv2 = MInt::<M>::from(2).inv();
611 let n = f.len() / 2;
612 let k = f.len().trailing_zeros() as usize;
613 let mut h = vec![MInt::<M>::zero(); n];
614 let w = MInt::<M>::new_unchecked(M::INFO.inv_root[k]);
615 BIT_REVERSE.with(|br| {
616 let br = unsafe { &mut *br.get() };
617 if br.len() < k {
618 br.resize_with(k, Default::default);
619 }
620 let k = k - 1;
621 if br[k].is_empty() {
622 let mut v = vec![0; 1 << k];
623 for i in 0..1 << k {
624 v[i] = (v[i >> 1] >> 1) | ((i & 1) << (k.saturating_sub(1)));
625 }
626 br[k] = v;
627 }
628 for &i in &br[k] {
629 h[i] = (f[i << 1] * g[i << 1 | 1] - f[i << 1 | 1] * g[i << 1]) * inv2;
630 inv2 *= w;
631 }
632 });
633 h
634 }
635}
636
637impl<M, N1, N2, N3> NttReuse for Convolve<(M, (N1, N2, N3))>
638where
639 M: MIntConvert + MIntConvert<u32>,
640 N1: Montgomery32NttModulus,
641 N2: Montgomery32NttModulus,
642 N3: Montgomery32NttModulus,
643{
644 fn ntt_doubling(f: Self::F) -> Self::F {
645 (
646 Convolve::<N1>::ntt_doubling(f.0),
647 Convolve::<N2>::ntt_doubling(f.1),
648 Convolve::<N3>::ntt_doubling(f.2),
649 )
650 }
651
652 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
653 fn even_mul_normal_neg_corrected<M>(f: &[MInt<M>], g: &[MInt<M>], m: u32) -> Vec<MInt<M>>
654 where
655 M: Montgomery32NttModulus,
656 {
657 let n = f.len();
658 assert_eq!(f.len(), g.len());
659 assert!(f.len().is_power_of_two());
660 assert!(f.len() >= 2);
661 let inv2 = MInt::<M>::from(2).inv();
662 let u = MInt::<M>::new(m) * MInt::<M>::from(n as u32);
663 let n = f.len() / 2;
664 (0..n)
665 .map(|i| {
666 (f[i << 1]
667 * if i == 0 {
668 g[i << 1 | 1] + u
669 } else {
670 g[i << 1 | 1]
671 }
672 + f[i << 1 | 1] * g[i << 1])
673 * inv2
674 })
675 .collect()
676 }
677
678 let m = M::mod_into();
679 (
680 even_mul_normal_neg_corrected(&f.0, &g.0, m),
681 even_mul_normal_neg_corrected(&f.1, &g.1, m),
682 even_mul_normal_neg_corrected(&f.2, &g.2, m),
683 )
684 }
685
686 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
687 fn odd_mul_normal_neg_corrected<M>(f: &[MInt<M>], g: &[MInt<M>], m: u32) -> Vec<MInt<M>>
688 where
689 M: Montgomery32NttModulus,
690 {
691 assert_eq!(f.len(), g.len());
692 assert!(f.len().is_power_of_two());
693 assert!(f.len() >= 2);
694 let mut inv2 = MInt::<M>::from(2).inv();
695 let u = MInt::<M>::new(m) * MInt::<M>::from(f.len() as u32);
696 let n = f.len() / 2;
697 let k = f.len().trailing_zeros() as usize;
698 let mut h = vec![MInt::<M>::zero(); n];
699 let w = MInt::<M>::new_unchecked(M::INFO.inv_root[k]);
700 BIT_REVERSE.with(|br| {
701 let br = unsafe { &mut *br.get() };
702 if br.len() < k {
703 br.resize_with(k, Default::default);
704 }
705 let k = k - 1;
706 if br[k].is_empty() {
707 let mut v = vec![0; 1 << k];
708 for i in 0..1 << k {
709 v[i] = (v[i >> 1] >> 1) | ((i & 1) << (k.saturating_sub(1)));
710 }
711 br[k] = v;
712 }
713 for &i in &br[k] {
714 h[i] = (f[i << 1]
715 * if i == 0 {
716 g[i << 1 | 1] + u
717 } else {
718 g[i << 1 | 1]
719 }
720 - f[i << 1 | 1] * g[i << 1])
721 * inv2;
722 inv2 *= w;
723 }
724 });
725 h
726 }pub fn get_mod() -> M::Inner
Sourcepub fn pow(self, y: usize) -> Self
pub fn pow(self, y: usize) -> Self
Examples found in repository?
More examples
Sourcepub fn inv(self) -> Self
pub fn inv(self) -> Self
Examples found in repository?
crates/competitive/src/math/number_theoretic_transform.rs (line 341)
338 fn inverse_transform(mut f: Self::F, len: usize) -> Self::T {
339 intt(&mut f);
340 f.truncate(len);
341 let inv = MInt::from(len.max(1).next_power_of_two() as u32).inv();
342 for f in f.iter_mut() {
343 *f *= inv;
344 }
345 f
346 }
347 fn multiply(f: &mut Self::F, g: &Self::F) {
348 assert_eq!(f.len(), g.len());
349 for (f, g) in f.iter_mut().zip(g.iter()) {
350 *f *= *g;
351 }
352 }
353 fn convolve(mut a: Self::T, mut b: Self::T) -> Self::T {
354 if Self::length(&a).max(Self::length(&b)) <= 100 {
355 return convolve_karatsuba(&a, &b);
356 }
357 if Self::length(&a).min(Self::length(&b)) <= 60 {
358 return convolve_naive(&a, &b);
359 }
360 let len = (Self::length(&a) + Self::length(&b)).saturating_sub(1);
361 let size = len.max(1).next_power_of_two();
362 if len <= size / 2 + 2 {
363 let xa = a.pop().unwrap();
364 let xb = b.pop().unwrap();
365 let mut c = vec![MInt::<M>::zero(); len];
366 *c.last_mut().unwrap() = xa * xb;
367 for (a, c) in a.iter().zip(&mut c[b.len()..]) {
368 *c += *a * xb;
369 }
370 for (b, c) in b.iter().zip(&mut c[a.len()..]) {
371 *c += *b * xa;
372 }
373 let d = Self::convolve(a, b);
374 for (d, c) in d.into_iter().zip(&mut c) {
375 *c += d;
376 }
377 return c;
378 }
379 let same = a == b;
380 let mut a = Self::transform(a, len);
381 if same {
382 for a in a.iter_mut() {
383 *a *= *a;
384 }
385 } else {
386 let b = Self::transform(b, len);
387 Self::multiply(&mut a, &b);
388 }
389 Self::inverse_transform(a, len)
390 }
391}
392
393type MVec<M> = Vec<MInt<M>>;
394impl<M, N1, N2, N3> ConvolveSteps for Convolve<(M, (N1, N2, N3))>
395where
396 M: MIntConvert + MIntConvert<u32>,
397 N1: Montgomery32NttModulus,
398 N2: Montgomery32NttModulus,
399 N3: Montgomery32NttModulus,
400{
401 type T = MVec<M>;
402 type F = (MVec<N1>, MVec<N2>, MVec<N3>);
403 fn length(t: &Self::T) -> usize {
404 t.len()
405 }
406 fn transform(t: Self::T, len: usize) -> Self::F {
407 let npot = len.max(1).next_power_of_two();
408 let mut f = (
409 MVec::<N1>::with_capacity(npot),
410 MVec::<N2>::with_capacity(npot),
411 MVec::<N3>::with_capacity(npot),
412 );
413 for t in t {
414 f.0.push(<M as MIntConvert<u32>>::into(t.inner()).into());
415 f.1.push(<M as MIntConvert<u32>>::into(t.inner()).into());
416 f.2.push(<M as MIntConvert<u32>>::into(t.inner()).into());
417 }
418 f.0.resize_with(npot, Zero::zero);
419 f.1.resize_with(npot, Zero::zero);
420 f.2.resize_with(npot, Zero::zero);
421 ntt(&mut f.0);
422 ntt(&mut f.1);
423 ntt(&mut f.2);
424 f
425 }
426 fn inverse_transform(f: Self::F, len: usize) -> Self::T {
427 let t1 = MInt::<N2>::new(N1::get_mod()).inv();
428 let m1 = MInt::<M>::from(N1::get_mod());
429 let m1_3 = MInt::<N3>::new(N1::get_mod());
430 let t2 = (m1_3 * MInt::<N3>::new(N2::get_mod())).inv();
431 let m2 = m1 * MInt::<M>::from(N2::get_mod());
432 Convolve::<N1>::inverse_transform(f.0, len)
433 .into_iter()
434 .zip(Convolve::<N2>::inverse_transform(f.1, len))
435 .zip(Convolve::<N3>::inverse_transform(f.2, len))
436 .map(|((c1, c2), c3)| {
437 let d1 = c1.inner();
438 let d2 = ((c2 - MInt::<N2>::from(d1)) * t1).inner();
439 let x = MInt::<N3>::new(d1) + MInt::<N3>::new(d2) * m1_3;
440 let d3 = ((c3 - x) * t2).inner();
441 MInt::<M>::from(d1) + MInt::<M>::from(d2) * m1 + MInt::<M>::from(d3) * m2
442 })
443 .collect()
444 }
445 fn multiply(f: &mut Self::F, g: &Self::F) {
446 assert_eq!(f.0.len(), g.0.len());
447 assert_eq!(f.1.len(), g.1.len());
448 assert_eq!(f.2.len(), g.2.len());
449 for (f, g) in f.0.iter_mut().zip(g.0.iter()) {
450 *f *= *g;
451 }
452 for (f, g) in f.1.iter_mut().zip(g.1.iter()) {
453 *f *= *g;
454 }
455 for (f, g) in f.2.iter_mut().zip(g.2.iter()) {
456 *f *= *g;
457 }
458 }
459 fn convolve(a: Self::T, b: Self::T) -> Self::T {
460 if Self::length(&a).max(Self::length(&b)) <= 300 {
461 return convolve_karatsuba(&a, &b);
462 }
463 if Self::length(&a).min(Self::length(&b)) <= 60 {
464 return convolve_naive(&a, &b);
465 }
466 let len = (Self::length(&a) + Self::length(&b)).saturating_sub(1);
467 let mut a = Self::transform(a, len);
468 let b = Self::transform(b, len);
469 Self::multiply(&mut a, &b);
470 Self::inverse_transform(a, len)
471 }
472}
473
474impl<N1, N2, N3> ConvolveSteps for Convolve<(u64, (N1, N2, N3))>
475where
476 N1: Montgomery32NttModulus,
477 N2: Montgomery32NttModulus,
478 N3: Montgomery32NttModulus,
479{
480 type T = Vec<u64>;
481 type F = (MVec<N1>, MVec<N2>, MVec<N3>);
482
483 fn length(t: &Self::T) -> usize {
484 t.len()
485 }
486
487 fn transform(t: Self::T, len: usize) -> Self::F {
488 let npot = len.max(1).next_power_of_two();
489 let mut f = (
490 MVec::<N1>::with_capacity(npot),
491 MVec::<N2>::with_capacity(npot),
492 MVec::<N3>::with_capacity(npot),
493 );
494 for t in t {
495 f.0.push(t.into());
496 f.1.push(t.into());
497 f.2.push(t.into());
498 }
499 f.0.resize_with(npot, Zero::zero);
500 f.1.resize_with(npot, Zero::zero);
501 f.2.resize_with(npot, Zero::zero);
502 ntt(&mut f.0);
503 ntt(&mut f.1);
504 ntt(&mut f.2);
505 f
506 }
507
508 fn inverse_transform(f: Self::F, len: usize) -> Self::T {
509 let t1 = MInt::<N2>::new(N1::get_mod()).inv();
510 let m1 = N1::get_mod() as u64;
511 let m1_3 = MInt::<N3>::new(N1::get_mod());
512 let t2 = (m1_3 * MInt::<N3>::new(N2::get_mod())).inv();
513 let m2 = m1 * N2::get_mod() as u64;
514 Convolve::<N1>::inverse_transform(f.0, len)
515 .into_iter()
516 .zip(Convolve::<N2>::inverse_transform(f.1, len))
517 .zip(Convolve::<N3>::inverse_transform(f.2, len))
518 .map(|((c1, c2), c3)| {
519 let d1 = c1.inner();
520 let d2 = ((c2 - MInt::<N2>::from(d1)) * t1).inner();
521 let x = MInt::<N3>::new(d1) + MInt::<N3>::new(d2) * m1_3;
522 let d3 = ((c3 - x) * t2).inner();
523 d1 as u64 + d2 as u64 * m1 + d3 as u64 * m2
524 })
525 .collect()
526 }
527
528 fn multiply(f: &mut Self::F, g: &Self::F) {
529 assert_eq!(f.0.len(), g.0.len());
530 assert_eq!(f.1.len(), g.1.len());
531 assert_eq!(f.2.len(), g.2.len());
532 for (f, g) in f.0.iter_mut().zip(g.0.iter()) {
533 *f *= *g;
534 }
535 for (f, g) in f.1.iter_mut().zip(g.1.iter()) {
536 *f *= *g;
537 }
538 for (f, g) in f.2.iter_mut().zip(g.2.iter()) {
539 *f *= *g;
540 }
541 }
542
543 fn convolve(a: Self::T, b: Self::T) -> Self::T {
544 if Self::length(&a).max(Self::length(&b)) <= 300 {
545 return convolve_karatsuba(&a, &b);
546 }
547 if Self::length(&a).min(Self::length(&b)) <= 60 {
548 return convolve_naive(&a, &b);
549 }
550 let len = (Self::length(&a) + Self::length(&b)).saturating_sub(1);
551 let mut a = Self::transform(a, len);
552 let b = Self::transform(b, len);
553 Self::multiply(&mut a, &b);
554 Self::inverse_transform(a, len)
555 }
556}
557
558pub trait NttReuse: ConvolveSteps {
559 const MULTIPLE: bool = true;
560
561 /// F(a) → F(a + [0] * a.len())
562 fn ntt_doubling(f: Self::F) -> Self::F;
563
564 /// F(a(x)), F(b(x)) → even(F(a(x) * b(-x)))
565 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F;
566
567 /// F(a(x)), F(b(x)) → odd(F(a(x) * b(-x)))
568 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F;
569}
570
571thread_local!(
572 static BIT_REVERSE: UnsafeCell<Vec<Vec<usize>>> = const { UnsafeCell::new(vec![]) };
573);
574
575impl<M> NttReuse for Convolve<M>
576where
577 M: Montgomery32NttModulus,
578{
579 const MULTIPLE: bool = false;
580
581 fn ntt_doubling(mut f: Self::F) -> Self::F {
582 let n = f.len();
583 let k = n.trailing_zeros() as usize;
584 let mut a = Self::inverse_transform(f.clone(), n);
585 let mut rot = MInt::<M>::one();
586 let zeta = MInt::<M>::new_unchecked(M::INFO.root[k + 1]);
587 for a in a.iter_mut() {
588 *a *= rot;
589 rot *= zeta;
590 }
591 f.extend(Self::transform(a, n));
592 f
593 }
594
595 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
596 assert_eq!(f.len(), g.len());
597 assert!(f.len().is_power_of_two());
598 assert!(f.len() >= 2);
599 let inv2 = MInt::<M>::from(2).inv();
600 let n = f.len() / 2;
601 (0..n)
602 .map(|i| (f[i << 1] * g[i << 1 | 1] + f[i << 1 | 1] * g[i << 1]) * inv2)
603 .collect()
604 }
605
606 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
607 assert_eq!(f.len(), g.len());
608 assert!(f.len().is_power_of_two());
609 assert!(f.len() >= 2);
610 let mut inv2 = MInt::<M>::from(2).inv();
611 let n = f.len() / 2;
612 let k = f.len().trailing_zeros() as usize;
613 let mut h = vec![MInt::<M>::zero(); n];
614 let w = MInt::<M>::new_unchecked(M::INFO.inv_root[k]);
615 BIT_REVERSE.with(|br| {
616 let br = unsafe { &mut *br.get() };
617 if br.len() < k {
618 br.resize_with(k, Default::default);
619 }
620 let k = k - 1;
621 if br[k].is_empty() {
622 let mut v = vec![0; 1 << k];
623 for i in 0..1 << k {
624 v[i] = (v[i >> 1] >> 1) | ((i & 1) << (k.saturating_sub(1)));
625 }
626 br[k] = v;
627 }
628 for &i in &br[k] {
629 h[i] = (f[i << 1] * g[i << 1 | 1] - f[i << 1 | 1] * g[i << 1]) * inv2;
630 inv2 *= w;
631 }
632 });
633 h
634 }
635}
636
637impl<M, N1, N2, N3> NttReuse for Convolve<(M, (N1, N2, N3))>
638where
639 M: MIntConvert + MIntConvert<u32>,
640 N1: Montgomery32NttModulus,
641 N2: Montgomery32NttModulus,
642 N3: Montgomery32NttModulus,
643{
644 fn ntt_doubling(f: Self::F) -> Self::F {
645 (
646 Convolve::<N1>::ntt_doubling(f.0),
647 Convolve::<N2>::ntt_doubling(f.1),
648 Convolve::<N3>::ntt_doubling(f.2),
649 )
650 }
651
652 fn even_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
653 fn even_mul_normal_neg_corrected<M>(f: &[MInt<M>], g: &[MInt<M>], m: u32) -> Vec<MInt<M>>
654 where
655 M: Montgomery32NttModulus,
656 {
657 let n = f.len();
658 assert_eq!(f.len(), g.len());
659 assert!(f.len().is_power_of_two());
660 assert!(f.len() >= 2);
661 let inv2 = MInt::<M>::from(2).inv();
662 let u = MInt::<M>::new(m) * MInt::<M>::from(n as u32);
663 let n = f.len() / 2;
664 (0..n)
665 .map(|i| {
666 (f[i << 1]
667 * if i == 0 {
668 g[i << 1 | 1] + u
669 } else {
670 g[i << 1 | 1]
671 }
672 + f[i << 1 | 1] * g[i << 1])
673 * inv2
674 })
675 .collect()
676 }
677
678 let m = M::mod_into();
679 (
680 even_mul_normal_neg_corrected(&f.0, &g.0, m),
681 even_mul_normal_neg_corrected(&f.1, &g.1, m),
682 even_mul_normal_neg_corrected(&f.2, &g.2, m),
683 )
684 }
685
686 fn odd_mul_normal_neg(f: &Self::F, g: &Self::F) -> Self::F {
687 fn odd_mul_normal_neg_corrected<M>(f: &[MInt<M>], g: &[MInt<M>], m: u32) -> Vec<MInt<M>>
688 where
689 M: Montgomery32NttModulus,
690 {
691 assert_eq!(f.len(), g.len());
692 assert!(f.len().is_power_of_two());
693 assert!(f.len() >= 2);
694 let mut inv2 = MInt::<M>::from(2).inv();
695 let u = MInt::<M>::new(m) * MInt::<M>::from(f.len() as u32);
696 let n = f.len() / 2;
697 let k = f.len().trailing_zeros() as usize;
698 let mut h = vec![MInt::<M>::zero(); n];
699 let w = MInt::<M>::new_unchecked(M::INFO.inv_root[k]);
700 BIT_REVERSE.with(|br| {
701 let br = unsafe { &mut *br.get() };
702 if br.len() < k {
703 br.resize_with(k, Default::default);
704 }
705 let k = k - 1;
706 if br[k].is_empty() {
707 let mut v = vec![0; 1 << k];
708 for i in 0..1 << k {
709 v[i] = (v[i >> 1] >> 1) | ((i & 1) << (k.saturating_sub(1)));
710 }
711 br[k] = v;
712 }
713 for &i in &br[k] {
714 h[i] = (f[i << 1]
715 * if i == 0 {
716 g[i << 1 | 1] + u
717 } else {
718 g[i << 1 | 1]
719 }
720 - f[i << 1 | 1] * g[i << 1])
721 * inv2;
722 inv2 *= w;
723 }
724 });
725 h
726 }More examples
crates/competitive/src/math/factorial.rs (line 22)
16 pub fn new(max_n: usize) -> Self {
17 let mut fact = vec![MInt::one(); max_n + 1];
18 let mut inv_fact = vec![MInt::one(); max_n + 1];
19 for i in 2..=max_n {
20 fact[i] = fact[i - 1] * MInt::from(i);
21 }
22 inv_fact[max_n] = fact[max_n].inv();
23 for i in (3..=max_n).rev() {
24 inv_fact[i - 1] = inv_fact[i] * MInt::from(i);
25 }
26 Self { fact, inv_fact }
27 }crates/competitive/src/math/black_box_matrix.rs (line 290)
279 fn black_box_linear_equation(&self, mut b: Vec<MInt<M>>) -> Option<Vec<MInt<M>>>
280 where
281 M: MIntConvert<u64>,
282 {
283 assert_eq!(self.shape().0, self.shape().1);
284 assert_eq!(self.shape().1, b.len());
285 let n = self.shape().0;
286 let p = self.minimal_polynomial();
287 if p.is_empty() || p[0].is_zero() {
288 return None;
289 }
290 let p0_inv = p[0].inv();
291 let mut x = vec![MInt::zero(); n];
292 for p in p.into_iter().skip(1) {
293 let p = -p * p0_inv;
294 for i in 0..n {
295 x[i] += p * b[i];
296 }
297 b = self.apply(&b);
298 }
299 Some(x)
300 }crates/library_checker/src/number_theory/sum_of_totient_function.rs (line 19)
12pub fn sum_of_totient_function(reader: impl Read, mut writer: impl Write) {
13 let s = read_all_unchecked(reader);
14 let mut scanner = Scanner::new(&s);
15 scan!(scanner, n: u64);
16 let mut s = 1;
17 let mut pp = 0;
18 let mut pc = 0;
19 let inv2 = M::new(2).inv();
20 let qa = QuotientArray::from_fn(n, |i| [M::from(i), M::from(i) * M::from(i + 1) * inv2])
21 .map(|[x, y]| [x - M::one(), y - M::one()])
22 .lucy_dp::<ArrayOperation<AdditiveOperation<_>, 2>>(|[x, y], p| [x, y * M::from(p)])
23 .map(|[x, y]| y - x)
24 .min_25_sieve::<AddMulOperation<_>>(|p, c| {
25 if pp != p || pc > c {
26 pp = p;
27 pc = 1;
28 s = p - 1;
29 }
30 while pc < c {
31 pc += 1;
32 s *= p;
33 }
34 M::from(s)
35 });
36 writeln!(writer, "{}", qa[n]).ok();
37}crates/competitive/src/math/lagrange_interpolation.rs (line 78)
50pub fn lagrange_interpolation_polynomial<M>(x: &[MInt<M>], y: &[MInt<M>]) -> Vec<MInt<M>>
51where
52 M: MIntBase,
53{
54 let n = x.len() - 1;
55 let mut dp = vec![MInt::zero(); n + 2];
56 let mut ndp = vec![MInt::zero(); n + 2];
57 dp[0] = -x[0];
58 dp[1] = MInt::one();
59 for x in x.iter().skip(1) {
60 for j in 0..=n + 1 {
61 ndp[j] = -dp[j] * x + if j >= 1 { dp[j - 1] } else { MInt::zero() };
62 }
63 std::mem::swap(&mut dp, &mut ndp);
64 }
65 let mut res = vec![MInt::zero(); n + 1];
66 for i in 0..=n {
67 let t = y[i]
68 / (0..=n)
69 .map(|j| if i != j { x[i] - x[j] } else { MInt::one() })
70 .product::<MInt<M>>();
71 if t.is_zero() {
72 continue;
73 } else if x[i].is_zero() {
74 for j in 0..=n {
75 res[j] += dp[j + 1] * t;
76 }
77 } else {
78 let xinv = x[i].inv();
79 let mut pre = MInt::zero();
80 for j in 0..=n {
81 let d = -(dp[j] - pre) * xinv;
82 res[j] += d * t;
83 pre = d;
84 }
85 }
86 }
87 res
88}crates/competitive/src/math/mint_matrix.rs (line 55)
41 fn determinant_linear_non_singular(mut self, mut other: Self) -> Option<Vec<MInt<M>>>
42 where
43 M: MIntBase,
44 {
45 let n = self.data.len();
46 let mut f = MInt::one();
47 for d in 0..n {
48 let i = other.data.iter().position(|other| !other[d].is_zero())?;
49 if i != d {
50 self.data.swap(i, d);
51 other.data.swap(i, d);
52 f = -f;
53 }
54 f *= other[d][d];
55 let r = other[d][d].inv();
56 for j in 0..n {
57 self[d][j] *= r;
58 other[d][j] *= r;
59 }
60 assert!(other[d][d].is_one());
61 for i in d + 1..n {
62 let a = other[i][d];
63 for k in 0..n {
64 self[i][k] = self[i][k] - a * self[d][k];
65 other[i][k] = other[i][k] - a * other[d][k];
66 }
67 }
68 for j in d + 1..n {
69 let a = other[d][j];
70 for k in 0..n {
71 self[k][j] = self[k][j] - a * self[k][d];
72 other[k][j] = other[k][j] - a * other[k][d];
73 }
74 }
75 }
76 for s in self.data.iter_mut() {
77 for s in s.iter_mut() {
78 *s = -*s;
79 }
80 }
81 let mut p = self.characteristic_polynomial();
82 for p in p.iter_mut() {
83 *p *= f;
84 }
85 Some(p)
86 }Sourcepub fn inner(self) -> M::Inner
pub fn inner(self) -> M::Inner
Examples found in repository?
crates/competitive/src/num/mint/mint_base.rs (line 107)
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 Debug::fmt(&self.inner(), f)
108 }
109}
110impl<M> Default for MInt<M>
111where
112 M: MIntBase,
113{
114 #[inline]
115 fn default() -> Self {
116 <Self as Zero>::zero()
117 }
118}
119impl<M> PartialEq for MInt<M>
120where
121 M: MIntBase,
122{
123 #[inline]
124 fn eq(&self, other: &Self) -> bool {
125 PartialEq::eq(&self.x, &other.x)
126 }
127}
128impl<M> Eq for MInt<M> where M: MIntBase {}
129impl<M> Hash for MInt<M>
130where
131 M: MIntBase,
132{
133 #[inline]
134 fn hash<H: Hasher>(&self, state: &mut H) {
135 Hash::hash(&self.x, state)
136 }
137}
138macro_rules! impl_mint_from {
139 ($($t:ty),*) => {
140 $(impl<M> From<$t> for MInt<M>
141 where
142 M: MIntConvert<$t>,
143 {
144 #[inline]
145 fn from(x: $t) -> Self {
146 Self::new_unchecked(<M as MIntConvert<$t>>::from(x))
147 }
148 }
149 impl<M> From<MInt<M>> for $t
150 where
151 M: MIntConvert<$t>,
152 {
153 #[inline]
154 fn from(x: MInt<M>) -> $t {
155 <M as MIntConvert<$t>>::into(x.x)
156 }
157 })*
158 };
159}
160impl_mint_from!(
161 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
162);
163impl<M> Zero for MInt<M>
164where
165 M: MIntBase,
166{
167 #[inline]
168 fn zero() -> Self {
169 Self::new_unchecked(M::mod_zero())
170 }
171}
172impl<M> One for MInt<M>
173where
174 M: MIntBase,
175{
176 #[inline]
177 fn one() -> Self {
178 Self::new_unchecked(M::mod_one())
179 }
180}
181
182impl<M> Add for MInt<M>
183where
184 M: MIntBase,
185{
186 type Output = Self;
187 #[inline]
188 fn add(self, rhs: Self) -> Self::Output {
189 Self::new_unchecked(M::mod_add(self.x, rhs.x))
190 }
191}
192impl<M> Sub for MInt<M>
193where
194 M: MIntBase,
195{
196 type Output = Self;
197 #[inline]
198 fn sub(self, rhs: Self) -> Self::Output {
199 Self::new_unchecked(M::mod_sub(self.x, rhs.x))
200 }
201}
202impl<M> Mul for MInt<M>
203where
204 M: MIntBase,
205{
206 type Output = Self;
207 #[inline]
208 fn mul(self, rhs: Self) -> Self::Output {
209 Self::new_unchecked(M::mod_mul(self.x, rhs.x))
210 }
211}
212impl<M> Div for MInt<M>
213where
214 M: MIntBase,
215{
216 type Output = Self;
217 #[inline]
218 fn div(self, rhs: Self) -> Self::Output {
219 Self::new_unchecked(M::mod_div(self.x, rhs.x))
220 }
221}
222impl<M> Neg for MInt<M>
223where
224 M: MIntBase,
225{
226 type Output = Self;
227 #[inline]
228 fn neg(self) -> Self::Output {
229 Self::new_unchecked(M::mod_neg(self.x))
230 }
231}
232impl<M> Sum for MInt<M>
233where
234 M: MIntBase,
235{
236 #[inline]
237 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
238 iter.fold(<Self as Zero>::zero(), Add::add)
239 }
240}
241impl<M> Product for MInt<M>
242where
243 M: MIntBase,
244{
245 #[inline]
246 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
247 iter.fold(<Self as One>::one(), Mul::mul)
248 }
249}
250impl<'a, M: 'a> Sum<&'a MInt<M>> for MInt<M>
251where
252 M: MIntBase,
253{
254 #[inline]
255 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
256 iter.fold(<Self as Zero>::zero(), Add::add)
257 }
258}
259impl<'a, M: 'a> Product<&'a MInt<M>> for MInt<M>
260where
261 M: MIntBase,
262{
263 #[inline]
264 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
265 iter.fold(<Self as One>::one(), Mul::mul)
266 }
267}
268impl<M> Display for MInt<M>
269where
270 M: MIntBase<Inner: Display>,
271{
272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
273 write!(f, "{}", self.inner())
274 }
275}
276impl<M> FromStr for MInt<M>
277where
278 M: MIntConvert + MIntBase<Inner: FromStr>,
279{
280 type Err = <M::Inner as FromStr>::Err;
281 #[inline]
282 fn from_str(s: &str) -> Result<Self, Self::Err> {
283 s.parse::<M::Inner>().map(Self::new)
284 }
285}
286impl<M> IterScan for MInt<M>
287where
288 M: MIntConvert + MIntBase<Inner: FromStr>,
289{
290 type Output = Self;
291 #[inline]
292 fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
293 iter.next()?.parse::<MInt<M>>().ok()
294 }
295}
296impl<M> SerdeByteStr for MInt<M>
297where
298 M: MIntBase<Inner: SerdeByteStr>,
299{
300 fn serialize(&self, buf: &mut Vec<u8>) {
301 self.inner().serialize(buf)
302 }More examples
crates/competitive/src/math/number_theoretic_transform.rs (line 414)
406 fn transform(t: Self::T, len: usize) -> Self::F {
407 let npot = len.max(1).next_power_of_two();
408 let mut f = (
409 MVec::<N1>::with_capacity(npot),
410 MVec::<N2>::with_capacity(npot),
411 MVec::<N3>::with_capacity(npot),
412 );
413 for t in t {
414 f.0.push(<M as MIntConvert<u32>>::into(t.inner()).into());
415 f.1.push(<M as MIntConvert<u32>>::into(t.inner()).into());
416 f.2.push(<M as MIntConvert<u32>>::into(t.inner()).into());
417 }
418 f.0.resize_with(npot, Zero::zero);
419 f.1.resize_with(npot, Zero::zero);
420 f.2.resize_with(npot, Zero::zero);
421 ntt(&mut f.0);
422 ntt(&mut f.1);
423 ntt(&mut f.2);
424 f
425 }
426 fn inverse_transform(f: Self::F, len: usize) -> Self::T {
427 let t1 = MInt::<N2>::new(N1::get_mod()).inv();
428 let m1 = MInt::<M>::from(N1::get_mod());
429 let m1_3 = MInt::<N3>::new(N1::get_mod());
430 let t2 = (m1_3 * MInt::<N3>::new(N2::get_mod())).inv();
431 let m2 = m1 * MInt::<M>::from(N2::get_mod());
432 Convolve::<N1>::inverse_transform(f.0, len)
433 .into_iter()
434 .zip(Convolve::<N2>::inverse_transform(f.1, len))
435 .zip(Convolve::<N3>::inverse_transform(f.2, len))
436 .map(|((c1, c2), c3)| {
437 let d1 = c1.inner();
438 let d2 = ((c2 - MInt::<N2>::from(d1)) * t1).inner();
439 let x = MInt::<N3>::new(d1) + MInt::<N3>::new(d2) * m1_3;
440 let d3 = ((c3 - x) * t2).inner();
441 MInt::<M>::from(d1) + MInt::<M>::from(d2) * m1 + MInt::<M>::from(d3) * m2
442 })
443 .collect()
444 }
445 fn multiply(f: &mut Self::F, g: &Self::F) {
446 assert_eq!(f.0.len(), g.0.len());
447 assert_eq!(f.1.len(), g.1.len());
448 assert_eq!(f.2.len(), g.2.len());
449 for (f, g) in f.0.iter_mut().zip(g.0.iter()) {
450 *f *= *g;
451 }
452 for (f, g) in f.1.iter_mut().zip(g.1.iter()) {
453 *f *= *g;
454 }
455 for (f, g) in f.2.iter_mut().zip(g.2.iter()) {
456 *f *= *g;
457 }
458 }
459 fn convolve(a: Self::T, b: Self::T) -> Self::T {
460 if Self::length(&a).max(Self::length(&b)) <= 300 {
461 return convolve_karatsuba(&a, &b);
462 }
463 if Self::length(&a).min(Self::length(&b)) <= 60 {
464 return convolve_naive(&a, &b);
465 }
466 let len = (Self::length(&a) + Self::length(&b)).saturating_sub(1);
467 let mut a = Self::transform(a, len);
468 let b = Self::transform(b, len);
469 Self::multiply(&mut a, &b);
470 Self::inverse_transform(a, len)
471 }
472}
473
474impl<N1, N2, N3> ConvolveSteps for Convolve<(u64, (N1, N2, N3))>
475where
476 N1: Montgomery32NttModulus,
477 N2: Montgomery32NttModulus,
478 N3: Montgomery32NttModulus,
479{
480 type T = Vec<u64>;
481 type F = (MVec<N1>, MVec<N2>, MVec<N3>);
482
483 fn length(t: &Self::T) -> usize {
484 t.len()
485 }
486
487 fn transform(t: Self::T, len: usize) -> Self::F {
488 let npot = len.max(1).next_power_of_two();
489 let mut f = (
490 MVec::<N1>::with_capacity(npot),
491 MVec::<N2>::with_capacity(npot),
492 MVec::<N3>::with_capacity(npot),
493 );
494 for t in t {
495 f.0.push(t.into());
496 f.1.push(t.into());
497 f.2.push(t.into());
498 }
499 f.0.resize_with(npot, Zero::zero);
500 f.1.resize_with(npot, Zero::zero);
501 f.2.resize_with(npot, Zero::zero);
502 ntt(&mut f.0);
503 ntt(&mut f.1);
504 ntt(&mut f.2);
505 f
506 }
507
508 fn inverse_transform(f: Self::F, len: usize) -> Self::T {
509 let t1 = MInt::<N2>::new(N1::get_mod()).inv();
510 let m1 = N1::get_mod() as u64;
511 let m1_3 = MInt::<N3>::new(N1::get_mod());
512 let t2 = (m1_3 * MInt::<N3>::new(N2::get_mod())).inv();
513 let m2 = m1 * N2::get_mod() as u64;
514 Convolve::<N1>::inverse_transform(f.0, len)
515 .into_iter()
516 .zip(Convolve::<N2>::inverse_transform(f.1, len))
517 .zip(Convolve::<N3>::inverse_transform(f.2, len))
518 .map(|((c1, c2), c3)| {
519 let d1 = c1.inner();
520 let d2 = ((c2 - MInt::<N2>::from(d1)) * t1).inner();
521 let x = MInt::<N3>::new(d1) + MInt::<N3>::new(d2) * m1_3;
522 let d3 = ((c3 - x) * t2).inner();
523 d1 as u64 + d2 as u64 * m1 + d3 as u64 * m2
524 })
525 .collect()
526 }Source§impl MInt<DynModuloU32>
impl MInt<DynModuloU32>
Sourcepub fn set_mod(m: u32)
pub fn set_mod(m: u32)
Examples found in repository?
crates/library_checker/src/number_theory/sqrt_mod.rs (line 11)
6pub fn sqrt_mod(reader: impl Read, mut writer: impl Write) {
7 let s = read_all_unchecked(reader);
8 let mut scanner = Scanner::new(&s);
9 scan!(scanner, q, yp: [(u32, u32)]);
10 for (y, p) in yp.take(q) {
11 DynMIntU32::set_mod(p);
12 if let Some(x) = DynMIntU32::from(y).sqrt() {
13 writeln!(writer, "{}", x).ok();
14 } else {
15 writeln!(writer, "-1").ok();
16 }
17 }
18}Trait Implementations§
Source§impl<M> AddAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
impl<M> AddAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
Source§fn add_assign(&mut self, other: &MInt<M>)
fn add_assign(&mut self, other: &MInt<M>)
Performs the
+= operation. Read moreSource§impl<M> AddAssign for MInt<M>where
M: MIntBase,
impl<M> AddAssign for MInt<M>where
M: MIntBase,
Source§fn add_assign(&mut self, rhs: MInt<M>)
fn add_assign(&mut self, rhs: MInt<M>)
Performs the
+= operation. Read moreSource§impl<M> DivAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
impl<M> DivAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
Source§fn div_assign(&mut self, other: &MInt<M>)
fn div_assign(&mut self, other: &MInt<M>)
Performs the
/= operation. Read moreSource§impl<M> DivAssign for MInt<M>where
M: MIntBase,
impl<M> DivAssign for MInt<M>where
M: MIntBase,
Source§fn div_assign(&mut self, rhs: MInt<M>)
fn div_assign(&mut self, rhs: MInt<M>)
Performs the
/= operation. Read moreSource§impl<M> FormalPowerSeriesCoefficient for MInt<M>where
M: MIntConvert<usize>,
impl<M> FormalPowerSeriesCoefficient for MInt<M>where
M: MIntConvert<usize>,
type Base = M
fn pow(self, exp: usize) -> Self
fn memorized_inv(mf: &MemorizedFactorial<Self::Base>, n: usize) -> Self
fn memorized_factorial(n: usize) -> MemorizedFactorial<Self::Base>
Source§impl<M> FormalPowerSeriesCoefficientSqrt for MInt<M>
impl<M> FormalPowerSeriesCoefficientSqrt for MInt<M>
fn sqrt_coefficient(&self) -> Option<Self>
Source§impl<M> MulAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
impl<M> MulAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
Source§fn mul_assign(&mut self, other: &MInt<M>)
fn mul_assign(&mut self, other: &MInt<M>)
Performs the
*= operation. Read moreSource§impl<M> MulAssign for MInt<M>where
M: MIntBase,
impl<M> MulAssign for MInt<M>where
M: MIntBase,
Source§fn mul_assign(&mut self, rhs: MInt<M>)
fn mul_assign(&mut self, rhs: MInt<M>)
Performs the
*= operation. Read moreSource§impl<M> RandomSpec<MInt<M>> for RangeFull
impl<M> RandomSpec<MInt<M>> for RangeFull
Source§impl<M> SerdeByteStr for MInt<M>where
M: MIntBase<Inner: SerdeByteStr>,
impl<M> SerdeByteStr for MInt<M>where
M: MIntBase<Inner: SerdeByteStr>,
Source§impl<M> SubAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
impl<M> SubAssign<&MInt<M>> for MInt<M>where
M: MIntBase,
Source§fn sub_assign(&mut self, other: &MInt<M>)
fn sub_assign(&mut self, other: &MInt<M>)
Performs the
-= operation. Read moreSource§impl<M> SubAssign for MInt<M>where
M: MIntBase,
impl<M> SubAssign for MInt<M>where
M: MIntBase,
Source§fn sub_assign(&mut self, rhs: MInt<M>)
fn sub_assign(&mut self, rhs: MInt<M>)
Performs the
-= operation. Read moreimpl<M> Copy for MInt<M>where
M: MIntBase,
impl<M> Eq for MInt<M>where
M: MIntBase,
Auto Trait Implementations§
impl<M> Freeze for MInt<M>
impl<M> RefUnwindSafe for MInt<M>
impl<M> Send for MInt<M>
impl<M> Sync for MInt<M>
impl<M> Unpin for MInt<M>
impl<M> UnwindSafe for MInt<M>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more