結果
問題 | No.1513 simple 門松列 problem |
ユーザー | to-omer |
提出日時 | 2021-05-21 22:43:47 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 184 ms / 3,000 ms |
コード長 | 27,861 bytes |
コンパイル時間 | 13,294 ms |
コンパイル使用メモリ | 397,676 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2024-10-10 09:25:55 |
合計ジャッジ時間 | 15,311 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,820 KB |
testcase_01 | AC | 1 ms
6,820 KB |
testcase_02 | AC | 181 ms
6,820 KB |
testcase_03 | AC | 1 ms
6,820 KB |
testcase_04 | AC | 1 ms
6,816 KB |
testcase_05 | AC | 1 ms
6,816 KB |
testcase_06 | AC | 1 ms
6,816 KB |
testcase_07 | AC | 1 ms
6,816 KB |
testcase_08 | AC | 1 ms
6,816 KB |
testcase_09 | AC | 1 ms
6,820 KB |
testcase_10 | AC | 1 ms
6,816 KB |
testcase_11 | AC | 1 ms
6,820 KB |
testcase_12 | AC | 1 ms
6,816 KB |
testcase_13 | AC | 1 ms
6,820 KB |
testcase_14 | AC | 180 ms
6,820 KB |
testcase_15 | AC | 184 ms
6,816 KB |
testcase_16 | AC | 182 ms
6,820 KB |
testcase_17 | AC | 110 ms
6,816 KB |
testcase_18 | AC | 37 ms
6,816 KB |
testcase_19 | AC | 3 ms
6,816 KB |
testcase_20 | AC | 20 ms
6,816 KB |
ソースコード
fn main() { #![allow(unused_imports, unused_macros)] prepare_io!(_in_buf, scanner, _out); macro_rules ! print { ($ ($ arg : tt) *) => (:: std :: write ! (_out , $ ($ arg) *) . expect ("io error")) } macro_rules ! println { ($ ($ arg : tt) *) => (:: std :: writeln ! (_out , $ ($ arg) *) . expect ("io error")) } scan!(scanner, n, k); let mut dp = vec![vec![(M::zero(), M::zero()); k]; k]; for i in 0..k { for j in 0..k { if i != j { dp[i][j] = (M::one(), M::from(i) + M::from(j)); } } } macro_rules! add_assign { ($l:expr, $r:expr) => {{ let x = $r.0; $l.0 += x; let x = $r.1; $l.1 += x; }}; } macro_rules! sub_assign { ($l:expr, $r:expr) => {{ let x = $r.0; $l.0 -= x; let x = $r.1; $l.1 -= x; }}; } for _ in 2..n { let mut ndp = vec![vec![(M::zero(), M::zero()); k]; k]; let mut acc = dp.clone(); for j in 0..k { for i in 1..j { add_assign!(acc[i][j], acc[i - 1][j]); } for i in (j + 1..k - 1).rev() { add_assign!(acc[i][j], acc[i + 1][j]); } } for j in 0..k { for l in 0..k { if j == l { continue; } if j < l { add_assign!(ndp[j][l], acc[j + 1][j]); sub_assign!(ndp[j][l], dp[l][j]); } else { add_assign!(ndp[j][l], acc[j - 1][j]); sub_assign!(ndp[j][l], dp[l][j]); } } } dp = ndp; for i in 0..k { for j in 0..k { let x = dp[i][j].0 * M::from(j); dp[i][j].1 += x; } } } let ans1 = dp .iter() .map(|dp| dp.iter().map(|dp| dp.0).sum::<M>()) .sum::<M>(); let ans2 = dp .iter() .map(|dp| dp.iter().map(|dp| dp.1).sum::<M>()) .sum::<M>(); println!("{} {}", ans1, ans2); } pub type M = mint_basic::MInt998244353; #[macro_export] macro_rules! prepare_io { ($ in_buf : ident , $ scanner : ident , $ out : ident) => { use std::io::{stdout, BufWriter, Write as _}; let $in_buf = read_stdin_all_unchecked(); let mut $scanner = Scanner::new(&$in_buf); let $out = stdout(); let mut $out = BufWriter::new($out.lock()); }; } pub fn echo<T: std::fmt::Display>( mut writer: impl std::io::Write, iter: impl IntoIterator<Item = T>, sep: impl std::fmt::Display, ) -> std::io::Result<()> { let mut iter = iter.into_iter(); if let Some(item) = iter.next() { write!(writer, "{}", item)?; } for item in iter { write!(writer, "{}{}", sep, item)?; } writeln!(writer) } pub fn read_stdin_all_unchecked() -> String { use std::io::Read as _; let mut buf = Vec::new(); std::io::stdin().read_to_end(&mut buf).expect("io error"); unsafe { String::from_utf8_unchecked(buf) } } pub fn read_stdin_line() -> String { let mut s = String::new(); std::io::stdin().read_line(&mut s).expect("io error"); s } pub use scanner_impls::{IterScan, MarkedIterScan, Scanner}; mod scanner_impls { pub trait IterScan: Sized { type Output; fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>; } pub trait MarkedIterScan: Sized { type Output; fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>; } #[derive(Clone, Debug)] pub struct Scanner<'a> { iter: std::str::SplitAsciiWhitespace<'a>, } impl<'a> Scanner<'a> { #[inline] pub fn new(s: &'a str) -> Self { let iter = s.split_ascii_whitespace(); Self { iter } } #[inline] pub fn scan<T>(&mut self) -> <T as IterScan>::Output where T: IterScan, { <T as IterScan>::scan(&mut self.iter).expect("scan error") } #[inline] pub fn mscan<T>(&mut self, marker: T) -> <T as MarkedIterScan>::Output where T: MarkedIterScan, { marker.mscan(&mut self.iter).expect("scan error") } #[inline] pub fn scan_vec<T>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> where T: IterScan, { (0..size) .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error")) .collect() } #[inline] pub fn iter<'b, T>(&'b mut self) -> ScannerIter<'a, 'b, T> where T: IterScan, { ScannerIter { inner: self, _marker: std::marker::PhantomData, } } } macro_rules ! iter_scan_impls { ($ ($ t : ty) *) => { $ (impl IterScan for $ t { type Output = Self ; # [inline] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I) -> Option < Self > { iter . next () ?. parse ::<$ t > () . ok () } }) * } ; } iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String); macro_rules ! iter_scan_tuple_impl { ($ ($ T : ident) *) => { impl <$ ($ T : IterScan) ,*> IterScan for ($ ($ T ,) *) { type Output = ($ (<$ T as IterScan >:: Output ,) *) ; # [inline] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It) -> Option < Self :: Output > { Some (($ (<$ T as IterScan >:: scan (_iter) ?,) *)) } } } ; } iter_scan_tuple_impl!(); iter_scan_tuple_impl!(A); iter_scan_tuple_impl ! (A B); iter_scan_tuple_impl ! (A B C); iter_scan_tuple_impl ! (A B C D); iter_scan_tuple_impl ! (A B C D E); iter_scan_tuple_impl ! (A B C D E F); iter_scan_tuple_impl ! (A B C D E F G); iter_scan_tuple_impl ! (A B C D E F G H); iter_scan_tuple_impl ! (A B C D E F G H I); iter_scan_tuple_impl ! (A B C D E F G H I J); iter_scan_tuple_impl ! (A B C D E F G H I J K); pub struct ScannerIter<'a, 'b, T> { inner: &'b mut Scanner<'a>, _marker: std::marker::PhantomData<fn() -> T>, } impl<'a, 'b, T> Iterator for ScannerIter<'a, 'b, T> where T: IterScan, { type Item = <T as IterScan>::Output; #[inline] fn next(&mut self) -> Option<Self::Item> { <T as IterScan>::scan(&mut self.inner.iter) } } } pub use marker_impls::{CharWithBase, Chars, CharsWithBase, Collect, SizedCollect, Usize1}; mod marker_impls { use super::*; use std::{ iter::{repeat_with, FromIterator}, marker::PhantomData, }; #[derive(Debug, Copy, Clone)] pub struct Usize1; impl IterScan for Usize1 { type Output = usize; #[inline] fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> { <usize as IterScan>::scan(iter)?.checked_sub(1) } } #[derive(Debug, Copy, Clone)] pub struct CharWithBase(pub char); impl MarkedIterScan for CharWithBase { type Output = usize; #[inline] fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> { Some((<char as IterScan>::scan(iter)? as u8 - self.0 as u8) as usize) } } #[derive(Debug, Copy, Clone)] pub struct Chars; impl IterScan for Chars { type Output = Vec<char>; #[inline] fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> { Some(iter.next()?.chars().collect()) } } #[derive(Debug, Copy, Clone)] pub struct CharsWithBase(pub char); impl MarkedIterScan for CharsWithBase { type Output = Vec<usize>; #[inline] fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> { Some( iter.next()? .chars() .map(|c| (c as u8 - self.0 as u8) as usize) .collect(), ) } } #[derive(Debug, Copy, Clone)] pub struct Collect<T, B = Vec<<T as IterScan>::Output>> where T: IterScan, B: FromIterator<<T as IterScan>::Output>, { size: usize, _marker: PhantomData<fn() -> (T, B)>, } impl<T, B> Collect<T, B> where T: IterScan, B: FromIterator<<T as IterScan>::Output>, { pub fn new(size: usize) -> Self { Self { size, _marker: PhantomData, } } } impl<T, B> MarkedIterScan for Collect<T, B> where T: IterScan, B: FromIterator<<T as IterScan>::Output>, { type Output = B; #[inline] fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> { repeat_with(|| <T as IterScan>::scan(iter)) .take(self.size) .collect() } } #[derive(Debug, Copy, Clone)] pub struct SizedCollect<T, B = Vec<<T as IterScan>::Output>> where T: IterScan, B: FromIterator<<T as IterScan>::Output>, { _marker: PhantomData<fn() -> (T, B)>, } impl<T, B> IterScan for SizedCollect<T, B> where T: IterScan, B: FromIterator<<T as IterScan>::Output>, { type Output = B; #[inline] fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> { let size = usize::scan(iter)?; repeat_with(|| <T as IterScan>::scan(iter)) .take(size) .collect() } } } #[macro_export] macro_rules ! scan_value { ($ scanner : expr , ($ ($ t : tt) ,*)) => { ($ ($ crate :: scan_value ! ($ scanner , $ t)) ,*) } ; ($ scanner : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | $ crate :: scan_value ! ($ scanner , $ t)) . collect ::< Vec < _ >> () } ; ($ scanner : expr , [$ t : ty ; $ len : expr]) => { $ scanner . scan_vec ::<$ t > ($ len) } ; ($ scanner : expr , [$ t : ty]) => { $ scanner . iter ::<$ t > () } ; ($ scanner : expr , { $ e : expr }) => { $ scanner . mscan ($ e) } ; ($ scanner : expr , $ t : ty) => { $ scanner . scan ::<$ t > () } ; } #[macro_export] macro_rules ! scan { ($ scanner : expr) => { } ; ($ scanner : expr ,) => { } ; ($ scanner : expr , mut $ var : tt : $ t : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , $ var : tt : $ t : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , mut $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , mut $ var : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , $ var : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , mut $ var : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; } pub mod mint_basic { use super::*; #[macro_export] macro_rules ! define_basic_mintbase { ($ name : ident , $ m : expr , $ basety : ty , $ signedty : ty , $ upperty : ty , [$ ($ unsigned : ty) ,*] , [$ ($ signed : ty) ,*]) => { pub struct $ name ; impl MIntBase for $ name { type Inner = $ basety ; # [inline] fn get_mod () -> Self :: Inner { $ m } # [inline] fn mod_zero () -> Self :: Inner { 0 } # [inline] fn mod_one () -> Self :: Inner { 1 } # [inline] fn mod_add (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { let z = x + y ; let m = Self :: get_mod () ; if z >= m { z - m } else { z } } # [inline] fn mod_sub (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { if x < y { x + Self :: get_mod () - y } else { x - y } } # [inline] fn mod_mul (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { (x as $ upperty * y as $ upperty % Self :: get_mod () as $ upperty) as $ basety } # [inline] fn mod_div (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { Self :: mod_mul (x , Self :: mod_inv (y)) } # [inline] fn mod_neg (x : Self :: Inner) -> Self :: Inner { if x == 0 { 0 } else { Self :: get_mod () - x } } fn mod_inv (x : Self :: Inner) -> Self :: Inner { let p = Self :: get_mod () as $ signedty ; let (mut a , mut b) = (x as $ signedty , p) ; let (mut u , mut x) = (1 , 0) ; while a != 0 { let k = b / a ; x -= k * u ; b -= k * a ; std :: mem :: swap (& mut x , & mut u) ; std :: mem :: swap (& mut b , & mut a) ; } (if x < 0 { x + p } else { x }) as _ } } $ (impl MIntConvert <$ unsigned > for $ name { # [inline] fn from (x : $ unsigned) -> Self :: Inner { (x % < Self as MIntBase >:: get_mod () as $ unsigned) as $ basety } # [inline] fn into (x : Self :: Inner) -> $ unsigned { x as $ unsigned } # [inline] fn mod_into () -> $ unsigned { < Self as MIntBase >:: get_mod () as $ unsigned } }) * $ (impl MIntConvert <$ signed > for $ name { # [inline] fn from (x : $ signed) -> Self :: Inner { let x = x % < Self as MIntBase >:: get_mod () as $ signed ; if x < 0 { (x + < Self as MIntBase >:: get_mod () as $ signed) as $ basety } else { x as $ basety } } # [inline] fn into (x : Self :: Inner) -> $ signed { x as $ signed } # [inline] fn mod_into () -> $ signed { < Self as MIntBase >:: get_mod () as $ signed } }) * } ; } #[macro_export] macro_rules ! define_basic_mint32 { ($ ([$ name : ident , $ m : expr , $ mint_name : ident]) ,*) => { $ (crate :: define_basic_mintbase ! ($ name , $ m , u32 , i32 , u64 , [u32 , u64 , u128 , usize] , [i32 , i64 , i128 , isize]) ; pub type $ mint_name = MInt <$ name >;) * } ; } define_basic_mint32!( [Modulo998244353, 998_244_353, MInt998244353], [Modulo1000000007, 1_000_000_007, MInt1000000007], [Modulo1000000009, 1_000_000_009, MInt1000000009], [ DynModuloU32, DYN_MODULUS_U32.with(|cell| unsafe { *cell.get() }), DynMIntU32 ] ); thread_local ! (static DYN_MODULUS_U32 : std :: cell :: UnsafeCell < u32 > = std :: cell :: UnsafeCell :: new (1_000_000_007)); impl DynModuloU32 { pub fn set_mod(m: u32) { DYN_MODULUS_U32.with(|cell| unsafe { *cell.get() = m }) } } thread_local ! (static DYN_MODULUS_U64 : std :: cell :: UnsafeCell < u64 > = std :: cell :: UnsafeCell :: new (1_000_000_007)); define_basic_mintbase!( DynModuloU64, DYN_MODULUS_U64.with(|cell| unsafe { *cell.get() }), u64, i64, u128, [u64, u128, usize], [i64, i128, isize] ); impl DynModuloU64 { pub fn set_mod(m: u64) { DYN_MODULUS_U64.with(|cell| unsafe { *cell.get() = m }) } } pub type DynMIntU64 = MInt<DynModuloU64>; pub struct Modulo2; impl MIntBase for Modulo2 { type Inner = u32; #[inline] fn get_mod() -> Self::Inner { 2 } #[inline] fn mod_zero() -> Self::Inner { 0 } #[inline] fn mod_one() -> Self::Inner { 1 } #[inline] fn mod_add(x: Self::Inner, y: Self::Inner) -> Self::Inner { x ^ y } #[inline] fn mod_sub(x: Self::Inner, y: Self::Inner) -> Self::Inner { x ^ y } #[inline] fn mod_mul(x: Self::Inner, y: Self::Inner) -> Self::Inner { x | y } #[inline] fn mod_div(x: Self::Inner, y: Self::Inner) -> Self::Inner { assert_ne!(y, 0); x } #[inline] fn mod_neg(x: Self::Inner) -> Self::Inner { x } #[inline] fn mod_inv(x: Self::Inner) -> Self::Inner { assert_ne!(x, 0); x } #[inline] fn mod_pow(x: Self::Inner, y: usize) -> Self::Inner { if y == 0 { 1 } else { x } } } macro_rules ! impl_to_mint_base_for_modulo2 { ($ name : ident , $ basety : ty , [$ ($ t : ty) ,*]) => { $ (impl MIntConvert <$ t > for $ name { # [inline] fn from (x : $ t) -> Self :: Inner { (x & 1) as $ basety } # [inline] fn into (x : Self :: Inner) -> $ t { x as $ t } # [inline] fn mod_into () -> $ t { 1 } }) * } ; } impl_to_mint_base_for_modulo2!( Modulo2, u32, [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize] ); pub type MInt2 = MInt<Modulo2>; } #[repr(transparent)] pub struct MInt<M> where M: MIntBase, { x: M::Inner, _marker: std::marker::PhantomData<fn() -> M>, } pub trait MIntBase { type Inner: Sized + Copy + Eq + std::fmt::Debug + std::hash::Hash; fn get_mod() -> Self::Inner; fn mod_zero() -> Self::Inner; fn mod_one() -> Self::Inner; fn mod_add(x: Self::Inner, y: Self::Inner) -> Self::Inner; fn mod_sub(x: Self::Inner, y: Self::Inner) -> Self::Inner; fn mod_mul(x: Self::Inner, y: Self::Inner) -> Self::Inner; fn mod_div(x: Self::Inner, y: Self::Inner) -> Self::Inner; fn mod_neg(x: Self::Inner) -> Self::Inner; fn mod_inv(x: Self::Inner) -> Self::Inner; fn mod_pow(x: Self::Inner, y: usize) -> Self::Inner { let (mut x, mut y, mut z) = (x, y, Self::mod_one()); while y > 0 { if y & 1 == 1 { z = Self::mod_mul(z, x); } x = Self::mod_mul(x, x); y >>= 1; } z } } pub trait MIntConvert<T = <Self as MIntBase>::Inner>: MIntBase { fn from(x: T) -> <Self as MIntBase>::Inner; fn into(x: <Self as MIntBase>::Inner) -> T; fn mod_into() -> T; } mod mint_base { use super::*; use std::{ fmt::{self, Debug, Display}, hash::{Hash, Hasher}, iter::{Product, Sum}, marker::PhantomData, ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}, str::FromStr, }; impl<M> MInt<M> where M: MIntConvert, { #[inline] pub fn new(x: M::Inner) -> Self { Self::new_unchecked(<M as MIntConvert<M::Inner>>::from(x)) } #[inline] pub fn inner(self) -> M::Inner { <M as MIntConvert<M::Inner>>::into(self.x) } } impl<M> MInt<M> where M: MIntBase, { #[inline] pub fn new_unchecked(x: M::Inner) -> Self { Self { x, _marker: PhantomData, } } #[inline] pub fn get_mod() -> M::Inner { M::get_mod() } #[inline] pub fn pow(self, y: usize) -> Self { Self::new_unchecked(M::mod_pow(self.x, y)) } #[inline] pub fn inv(self) -> Self { Self::new_unchecked(M::mod_inv(self.x)) } } impl<M> Clone for MInt<M> where M: MIntBase, { #[inline] fn clone(&self) -> Self { Self { x: Clone::clone(&self.x), _marker: PhantomData, } } } impl<M> Copy for MInt<M> where M: MIntBase {} impl<M> Debug for MInt<M> where M: MIntBase, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Debug::fmt(&self.x, f) } } impl<M> Default for MInt<M> where M: MIntBase, { #[inline] fn default() -> Self { <Self as Zero>::zero() } } impl<M> PartialEq for MInt<M> where M: MIntBase, { #[inline] fn eq(&self, other: &Self) -> bool { PartialEq::eq(&self.x, &other.x) } } impl<M> Eq for MInt<M> where M: MIntBase {} impl<M> Hash for MInt<M> where M: MIntBase, { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { Hash::hash(&self.x, state) } } macro_rules ! impl_mint_from { ($ ($ t : ty) ,*) => { $ (impl < M > From <$ t > for MInt < M > where M : MIntConvert <$ t >, { # [inline] fn from (x : $ t) -> Self { Self :: new_unchecked (< M as MIntConvert <$ t >>:: from (x)) } } impl < M > From < MInt < M >> for $ t where M : MIntConvert <$ t >, { # [inline] fn from (x : MInt < M >) -> $ t { < M as MIntConvert <$ t >>:: into (x . x) } }) * } ; } impl_mint_from!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); impl<M> Zero for MInt<M> where M: MIntBase, { #[inline] fn zero() -> Self { Self::new_unchecked(M::mod_zero()) } } impl<M> One for MInt<M> where M: MIntBase, { #[inline] fn one() -> Self { Self::new_unchecked(M::mod_one()) } } impl<M> Add for MInt<M> where M: MIntBase, { type Output = Self; #[inline] fn add(self, rhs: Self) -> Self::Output { Self::new_unchecked(M::mod_add(self.x, rhs.x)) } } impl<M> Sub for MInt<M> where M: MIntBase, { type Output = Self; #[inline] fn sub(self, rhs: Self) -> Self::Output { Self::new_unchecked(M::mod_sub(self.x, rhs.x)) } } impl<M> Mul for MInt<M> where M: MIntBase, { type Output = Self; #[inline] fn mul(self, rhs: Self) -> Self::Output { Self::new_unchecked(M::mod_mul(self.x, rhs.x)) } } impl<M> Div for MInt<M> where M: MIntBase, { type Output = Self; #[inline] fn div(self, rhs: Self) -> Self::Output { Self::new_unchecked(M::mod_div(self.x, rhs.x)) } } impl<M> Neg for MInt<M> where M: MIntBase, { type Output = Self; #[inline] fn neg(self) -> Self::Output { Self::new_unchecked(M::mod_neg(self.x)) } } impl<M> Sum for MInt<M> where M: MIntBase, { #[inline] fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { iter.fold(<Self as Zero>::zero(), Add::add) } } impl<M> Product for MInt<M> where M: MIntBase, { #[inline] fn product<I: Iterator<Item = Self>>(iter: I) -> Self { iter.fold(<Self as One>::one(), Mul::mul) } } impl<'a, M: 'a> Sum<&'a MInt<M>> for MInt<M> where M: MIntBase, { #[inline] fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self { iter.fold(<Self as Zero>::zero(), Add::add) } } impl<'a, M: 'a> Product<&'a MInt<M>> for MInt<M> where M: MIntBase, { #[inline] fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self { iter.fold(<Self as One>::one(), Mul::mul) } } impl<M> Display for MInt<M> where M: MIntConvert, M::Inner: Display, { fn fmt<'a>(&self, f: &mut fmt::Formatter<'a>) -> Result<(), fmt::Error> { write!(f, "{}", self.inner()) } } impl<M> FromStr for MInt<M> where M: MIntConvert, M::Inner: FromStr, { type Err = <M::Inner as FromStr>::Err; #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { s.parse::<M::Inner>().map(Self::new) } } impl<M> IterScan for MInt<M> where M: MIntConvert, M::Inner: FromStr, { type Output = Self; #[inline] fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> { iter.next()?.parse::<MInt<M>>().ok() } } macro_rules! impl_mint_ref_binop { ($ imp : ident , $ method : ident , $ t : ty) => { impl<M> $imp<$t> for &$t where M: MIntBase, { type Output = <$t as $imp<$t>>::Output; #[inline] fn $method(self, other: $t) -> <$t as $imp<$t>>::Output { $imp::$method(*self, other) } } impl<M> $imp<&$t> for $t where M: MIntBase, { type Output = <$t as $imp<$t>>::Output; #[inline] fn $method(self, other: &$t) -> <$t as $imp<$t>>::Output { $imp::$method(self, *other) } } impl<M> $imp<&$t> for &$t where M: MIntBase, { type Output = <$t as $imp<$t>>::Output; #[inline] fn $method(self, other: &$t) -> <$t as $imp<$t>>::Output { $imp::$method(*self, *other) } } }; } impl_mint_ref_binop!(Add, add, MInt<M>); impl_mint_ref_binop!(Sub, sub, MInt<M>); impl_mint_ref_binop!(Mul, mul, MInt<M>); impl_mint_ref_binop!(Div, div, MInt<M>); macro_rules! impl_mint_ref_unop { ($ imp : ident , $ method : ident , $ t : ty) => { impl<M> $imp for &$t where M: MIntBase, { type Output = <$t as $imp>::Output; #[inline] fn $method(self) -> <$t as $imp>::Output { $imp::$method(*self) } } }; } impl_mint_ref_unop!(Neg, neg, MInt<M>); macro_rules! impl_mint_ref_op_assign { ($ imp : ident , $ method : ident , $ t : ty , $ fromimp : ident , $ frommethod : ident) => { impl<M> $imp<$t> for $t where M: MIntBase, { #[inline] fn $method(&mut self, rhs: $t) { *self = $fromimp::$frommethod(*self, rhs); } } impl<M> $imp<&$t> for $t where M: MIntBase, { #[inline] fn $method(&mut self, other: &$t) { $imp::$method(self, *other); } } }; } impl_mint_ref_op_assign!(AddAssign, add_assign, MInt<M>, Add, add); impl_mint_ref_op_assign!(SubAssign, sub_assign, MInt<M>, Sub, sub); impl_mint_ref_op_assign!(MulAssign, mul_assign, MInt<M>, Mul, mul); impl_mint_ref_op_assign!(DivAssign, div_assign, MInt<M>, Div, div); } pub trait Zero: Sized { fn zero() -> Self; #[inline] fn is_zero(&self) -> bool where Self: PartialEq, { self == &Self::zero() } #[inline] fn set_zero(&mut self) { *self = Self::zero(); } } pub trait One: Sized { fn one() -> Self; #[inline] fn is_one(&self) -> bool where Self: PartialEq, { self == &Self::one() } #[inline] fn set_one(&mut self) { *self = Self::one(); } } macro_rules ! zero_one_impls { ($ ({ $ Trait : ident $ method : ident $ ($ t : ty) *, $ e : expr }) *) => { $ ($ (impl $ Trait for $ t { fn $ method () -> Self { $ e } }) *) * } ; } zero_one_impls ! ({ Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 0 } { Zero zero f32 f64 , 0. } { One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 1 } { One one f32 f64 , 1. });