結果
問題 | No.1750 ラムドスウイルスの感染拡大-hard |
ユーザー |
![]() |
提出日時 | 2021-11-19 22:03:00 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 295 ms / 2,000 ms |
コード長 | 35,734 bytes |
コンパイル時間 | 30,202 ms |
コンパイル使用メモリ | 402,480 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2025-01-01 17:42:45 |
合計ジャッジ時間 | 15,750 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge7 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 30 |
コンパイルメッセージ
warning: fields `sum_e` and `sum_ie` are never read --> src/main.rs:735:20 | 734 | pub struct ButterflyCache<M> { | -------------- fields in this struct 735 | pub(crate) sum_e: Vec<StaticModInt<M>>, | ^^^^^ 736 | pub(crate) sum_ie: Vec<StaticModInt<M>>, | ^^^^^^ | = note: `#[warn(dead_code)]` on by default
ソースコード
#[allow(unused_imports)]use std::io::{stdout, BufWriter, Write};fn main() {let out = stdout();let mut out = BufWriter::new(out.lock());inputv! {n:usize,m:usize,t:u64,}let mut graph = Matrix::new(n, n, ModInt998244353::new(0));let mut v = Matrix::new(n, 1, ModInt998244353::new(0));v[0][0] += 1;for _ in 0..m {inputv! {a:usize,b:usize,}graph[a][b] += 1;graph[b][a] += 1;}let graph = graph.pow(t, ModInt998244353::new(1));let ans = &graph * &v;writeln!(out, "{}", ans[0][0]).unwrap();}//https://github.com/rust-lang-ja/ac-library-rs//https://github.com/manta1130/competitive-template-rsuse input::*;use matrix::*;use modint::*;pub mod input {use std::cell::RefCell;use std::io;pub const SPLIT_DELIMITER: char = ' ';pub use std::io::prelude::*;thread_local! {pub static INPUT_BUFFER:RefCell<std::collections::VecDeque<String>>=RefCell::new(std::collections::VecDeque::new());}#[macro_export]macro_rules! input_internal {($x:ident : $t:ty) => {INPUT_BUFFER.with(|p| {if p.borrow().len() == 0 {let temp_str = input_line_str();let mut split_result_iter = temp_str.split(SPLIT_DELIMITER).map(|q| q.to_string()).collect::<std::collections::VecDeque<_>>();p.borrow_mut().append(&mut split_result_iter)}});let mut buf_split_result = String::new();INPUT_BUFFER.with(|p| buf_split_result = p.borrow_mut().pop_front().unwrap());let $x: $t = buf_split_result.parse().unwrap();};(mut $x:ident : $t:ty) => {INPUT_BUFFER.with(|p| {if p.borrow().len() == 0 {let temp_str = input_line_str();let mut split_result_iter = temp_str.split(SPLIT_DELIMITER).map(|q| q.to_string()).collect::<std::collections::VecDeque<_>>();p.borrow_mut().append(&mut split_result_iter)}});let mut buf_split_result = String::new();INPUT_BUFFER.with(|p| buf_split_result = p.borrow_mut().pop_front().unwrap());let mut $x: $t = buf_split_result.parse().unwrap();};}pub fn input_buffer_is_empty() -> bool {let mut empty = false;INPUT_BUFFER.with(|p| {if p.borrow().len() == 0 {empty = true;}});empty}#[macro_export]macro_rules! inputv {($i:ident : $t:ty) => {input_internal!{$i : $t}};(mut $i:ident : $t:ty) => {input_internal!{mut $i : $t}};($i:ident : $t:ty $(,)*) => {input_internal!{$i : $t}};(mut $i:ident : $t:ty $(,)*) => {input_internal!{mut $i : $t}};(mut $i:ident : $t:ty,$($q:tt)*) => {input_internal!{mut $i : $t}inputv!{$($q)*}};($i:ident : $t:ty,$($q:tt)*) => {input_internal!{$i : $t}inputv!{$($q)*}};}pub fn input_all() {INPUT_BUFFER.with(|p| {if p.borrow().len() == 0 {let mut temp_str = String::new();std::io::stdin().read_to_string(&mut temp_str).unwrap();let mut split_result_iter = temp_str.split_whitespace().map(|q| q.to_string()).collect::<std::collections::VecDeque<_>>();p.borrow_mut().append(&mut split_result_iter)}});}pub fn input_line_str() -> String {let mut s = String::new();io::stdin().read_line(&mut s).unwrap();s.trim().to_string()}#[allow(clippy::match_wild_err_arm)]pub fn input_vector<T>() -> Vec<T>whereT: std::str::FromStr,{let mut v: Vec<T> = Vec::new();let s = input_line_str();let split_result = s.split(SPLIT_DELIMITER);for z in split_result {let buf = match z.parse() {Ok(r) => r,Err(_) => panic!("Parse Error",),};v.push(buf);}v}#[allow(clippy::match_wild_err_arm)]pub fn input_vector_row<T>(n: usize) -> Vec<T>whereT: std::str::FromStr,{let mut v = Vec::with_capacity(n);for _ in 0..n {let buf = match input_line_str().parse() {Ok(r) => r,Err(_) => panic!("Parse Error",),};v.push(buf);}v}pub trait ToCharVec {fn to_charvec(&self) -> Vec<char>;}impl ToCharVec for String {fn to_charvec(&self) -> Vec<char> {self.to_string().chars().collect::<Vec<_>>()}}}pub mod internal_math {#![allow(dead_code)]use std::mem::swap;/* const */pub(crate) fn safe_mod(mut x: i64, m: i64) -> i64 {x %= m;if x < 0 {x += m;}x}pub(crate) struct Barrett {pub(crate) _m: u32,pub(crate) im: u64,}impl Barrett {pub(crate) fn new(m: u32) -> Barrett {Barrett {_m: m,im: (-1i64 as u64 / m as u64).wrapping_add(1),}}pub(crate) fn umod(&self) -> u32 {self._m}#[allow(clippy::many_single_char_names)]pub(crate) fn mul(&self, a: u32, b: u32) -> u32 {mul_mod(a, b, self._m, self.im)}}#[allow(clippy::many_single_char_names)]pub(crate) fn mul_mod(a: u32, b: u32, m: u32, im: u64) -> u32 {let mut z = a as u64;z *= b as u64;let x = (((z as u128) * (im as u128)) >> 64) as u64;let mut v = z.wrapping_sub(x.wrapping_mul(m as u64)) as u32;if m <= v {v = v.wrapping_add(m);}v}/* const */#[allow(clippy::many_single_char_names)]pub(crate) fn pow_mod(x: i64, mut n: i64, m: i32) -> i64 {if m == 1 {return 0;}let _m = m as u32;let mut r: u64 = 1;let mut y: u64 = safe_mod(x, m as i64) as u64;while n != 0 {if (n & 1) > 0 {r = (r * y) % (_m as u64);}y = (y * y) % (_m as u64);n >>= 1;}r as i64}/* const */pub(crate) fn is_prime(n: i32) -> bool {let n = n as i64;match n {_ if n <= 1 => return false,2 | 7 | 61 => return true,_ if n % 2 == 0 => return false,_ => {}}let mut d = n - 1;while d % 2 == 0 {d /= 2;}for &a in &[2, 7, 61] {let mut t = d;let mut y = pow_mod(a, t, n as i32);while t != n - 1 && y != 1 && y != n - 1 {y = y * y % n;t <<= 1;}if y != n - 1 && t % 2 == 0 {return false;}}true}/* const */#[allow(clippy::many_single_char_names)]pub(crate) fn inv_gcd(a: i64, b: i64) -> (i64, i64) {let a = safe_mod(a, b);if a == 0 {return (b, 0);}let mut s = b;let mut t = a;let mut m0 = 0;let mut m1 = 1;while t != 0 {let u = s / t;s -= t * u;m0 -= m1 * u; // |m1 * u| <= |m1| * s <= bswap(&mut s, &mut t);swap(&mut m0, &mut m1);}if m0 < 0 {m0 += b / s;}(s, m0)}/* const */pub(crate) fn primitive_root(m: i32) -> i32 {match m {2 => return 1,167_772_161 => return 3,469_762_049 => return 3,754_974_721 => return 11,998_244_353 => return 3,_ => {}}let mut divs = [0; 20];divs[0] = 2;let mut cnt = 1;let mut x = (m - 1) / 2;while x % 2 == 0 {x /= 2;}for i in (3..std::i32::MAX).step_by(2) {if i as i64 * i as i64 > x as i64 {break;}if x % i == 0 {divs[cnt] = i;cnt += 1;while x % i == 0 {x /= i;}}}if x > 1 {divs[cnt] = x;cnt += 1;}let mut g = 2;loop {if (0..cnt).all(|i| pow_mod(g, ((m - 1) / divs[i]) as i64, m) != 1) {break g as i32;}g += 1;}}}pub mod matrix {use std::fmt;use std::ops::{Add, AddAssign, Deref, DerefMut, Div, Mul, MulAssign, Sub, SubAssign};#[derive(Clone, PartialEq, Debug)]pub struct Matrix<T> {v: Vec<Vec<T>>,}impl<T> Matrix<T>whereT: Copy,{pub fn new(h: usize, w: usize, init: T) -> Matrix<T> {Matrix {v: vec![vec![init; w]; h],}}pub fn from(v: Vec<Vec<T>>) -> Matrix<T> {Matrix { v }}pub fn h(&self) -> usize {self.v.len()}pub fn w(&self) -> usize {self.v[0].len()}pub fn chrow(&mut self, a: usize, b: usize) {self.v.swap(a, b);}pub fn chcol(&mut self, a: usize, b: usize) {for i in 0..self.v.len() {self.v[i].swap(a, b);}}}impl<T> fmt::Display for Matrix<T>whereT: fmt::Debug,{fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {let mut first = true;for l in &self.v {if !first {writeln!(f).unwrap();}first = false;for k in l {write!(f, "{:?} ", k).unwrap();}}write!(f, "")}}impl<T> Matrix<T>whereT: Copy + AddAssign + Sub<Output = T> + Default,{pub fn t(&self) -> Matrix<T> {let mut r = Matrix::new(self.w(), self.h(), T::default());for i in 0..self.h() {for j in 0..self.w() {r[j][i] = self[i][j];}}r}}impl<T> Matrix<T>whereT: Copy+ Add<Output = T>+ Sub<Output = T>+ MulAssign+ Mul<Output = T>+ AddAssign+ Div<Output = T>+ Default,{pub fn pow(&self, mut p: u64, init: T) -> Matrix<T> {let mut r = Matrix::new(self.h(), self.w(), T::default());for i in 0..r.len() {r[i][i] = init;}let mut buf = self.clone();while p > 0 {if p & 1 == 1 {r = &r * &buf;}buf = &buf * &buf;p >>= 1;}r}}impl<T> Add for &Matrix<T>whereT: Copy + Add<Output = T> + Sub<Output = T> + MulAssign + Default,{type Output = Matrix<T>;fn add(self, other: &Matrix<T>) -> Matrix<T> {assert_eq!(self.h(), other.h());assert_eq!(self.w(), other.w());let mut r = Matrix::new(self.h(), self.w(), T::default());for i in 0..self.h() {for j in 0..self.w() {r[i][j] = self[i][j] + other[i][j];}}r}}impl<T> Add<T> for &Matrix<T>whereT: Copy + AddAssign,{type Output = Matrix<T>;fn add(self, other: T) -> Matrix<T> {let mut r = self.clone();for i in 0..self.h() {for j in 0..self.w() {r[i][j] += other;}}r}}impl<T> AddAssign<T> for Matrix<T>whereT: Copy + AddAssign,{fn add_assign(&mut self, other: T) {for i in 0..self.h() {for j in 0..self.w() {self[i][j] += other;}}}}impl<T> Sub for &Matrix<T>whereT: Copy + Sub<Output = T> + Default,{type Output = Matrix<T>;fn sub(self, other: &Matrix<T>) -> Matrix<T> {assert_eq!(self.h(), other.h());assert_eq!(self.w(), other.w());let mut r = Matrix::new(self.h(), self.w(), T::default());for i in 0..self.h() {for j in 0..self.w() {r[i][j] = self[i][j] - other[i][j];}}r}}impl<T> Sub<T> for &Matrix<T>whereT: Copy + SubAssign,{type Output = Matrix<T>;fn sub(self, other: T) -> Matrix<T> {let mut r = self.clone();for i in 0..self.h() {for j in 0..self.w() {r[i][j] -= other;}}r}}impl<T> SubAssign<T> for Matrix<T>whereT: Copy + SubAssign,{fn sub_assign(&mut self, other: T) {for i in 0..self.h() {for j in 0..self.w() {self[i][j] -= other;}}}}impl<T> Mul for &Matrix<T>whereT: Copy + Sub<Output = T> + AddAssign + Mul<Output = T> + Default,{type Output = Matrix<T>;fn mul(self, other: &Matrix<T>) -> Matrix<T> {assert_eq!(self.w(), other.h());let mut r = Matrix::new(self.h(), other.w(), T::default());for i in 0..r.h() {for j in 0..r.w() {for q in 0..self.w() {r[i][j] += self[i][q] * other[q][j];}}}r}}impl<T> Mul<T> for &Matrix<T>whereT: Copy + MulAssign,{type Output = Matrix<T>;fn mul(self, other: T) -> Matrix<T> {let mut r = self.clone();for i in 0..self.h() {for j in 0..self.w() {r[i][j] *= other;}}r}}impl<T> MulAssign<T> for Matrix<T>whereT: Copy + MulAssign,{fn mul_assign(&mut self, other: T) {for i in 0..self.h() {for j in 0..self.w() {self[i][j] *= other;}}}}impl<T> Deref for Matrix<T> {type Target = Vec<Vec<T>>;fn deref(&self) -> &Vec<Vec<T>> {&self.v}}impl<T> DerefMut for Matrix<T> {fn deref_mut(&mut self) -> &mut Vec<Vec<T>> {&mut self.v}}}pub mod modint {use crate::internal_math;use std::{cell::RefCell,convert::{Infallible, TryInto as _},fmt,hash::{Hash, Hasher},iter::{Product, Sum},marker::PhantomData,ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},str::FromStr,sync::atomic::{self, AtomicU32, AtomicU64},thread::LocalKey,};pub type ModInt1000000007 = StaticModInt<Mod1000000007>;pub type ModInt998244353 = StaticModInt<Mod998244353>;pub type ModInt = DynamicModInt<DefaultId>;#[derive(Copy, Clone, Eq, PartialEq)]#[repr(transparent)]pub struct StaticModInt<M> {val: u32,phantom: PhantomData<fn() -> M>,}impl<M: Modulus> StaticModInt<M> {#[inline(always)]pub fn modulus() -> u32 {M::VALUE}#[inline]pub fn new<T: RemEuclidU32>(val: T) -> Self {Self::raw(val.rem_euclid_u32(M::VALUE))}#[inline]pub fn raw(val: u32) -> Self {Self {val,phantom: PhantomData,}}#[inline]pub fn val(self) -> u32 {self.val}#[inline]pub fn pow(self, n: u64) -> Self {<Self as ModIntBase>::pow(self, n)}#[inline]pub fn inv(self) -> Self {if M::HINT_VALUE_IS_PRIME {if self.val() == 0 {panic!("attempt to divide by zero");}debug_assert!(internal_math::is_prime(M::VALUE.try_into().unwrap()),"{} is not a prime number",M::VALUE,);self.pow((M::VALUE - 2).into())} else {Self::inv_for_non_prime_modulus(self)}}}impl<M: Modulus> ModIntBase for StaticModInt<M> {#[inline(always)]fn modulus() -> u32 {Self::modulus()}#[inline]fn raw(val: u32) -> Self {Self::raw(val)}#[inline]fn val(self) -> u32 {self.val()}#[inline]fn inv(self) -> Self {self.inv()}}pub trait Modulus: 'static + Copy + Eq {const VALUE: u32;const HINT_VALUE_IS_PRIME: bool;fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>>;}#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]pub enum Mod1000000007 {}impl Modulus for Mod1000000007 {const VALUE: u32 = 1_000_000_007;const HINT_VALUE_IS_PRIME: bool = true;fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>> {thread_local! {static BUTTERFLY_CACHE: RefCell<Option<ButterflyCache<Mod1000000007>>> = RefCell::default();}&BUTTERFLY_CACHE}}#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]pub enum Mod998244353 {}impl Modulus for Mod998244353 {const VALUE: u32 = 998_244_353;const HINT_VALUE_IS_PRIME: bool = true;fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>> {thread_local! {static BUTTERFLY_CACHE: RefCell<Option<ButterflyCache<Mod998244353>>> = RefCell::default();}&BUTTERFLY_CACHE}}pub struct ButterflyCache<M> {pub(crate) sum_e: Vec<StaticModInt<M>>,pub(crate) sum_ie: Vec<StaticModInt<M>>,}#[derive(Copy, Clone, Eq, PartialEq)]#[repr(transparent)]pub struct DynamicModInt<I> {val: u32,phantom: PhantomData<fn() -> I>,}impl<I: Id> DynamicModInt<I> {#[inline]pub fn modulus() -> u32 {I::companion_barrett().umod()}#[inline]pub fn set_modulus(modulus: u32) {if modulus == 0 {panic!("the modulus must not be 0");}I::companion_barrett().update(modulus);}#[inline]pub fn new<T: RemEuclidU32>(val: T) -> Self {<Self as ModIntBase>::new(val)}#[inline]pub fn raw(val: u32) -> Self {Self {val,phantom: PhantomData,}}#[inline]pub fn val(self) -> u32 {self.val}#[inline]pub fn pow(self, n: u64) -> Self {<Self as ModIntBase>::pow(self, n)}#[inline]pub fn inv(self) -> Self {Self::inv_for_non_prime_modulus(self)}}impl<I: Id> ModIntBase for DynamicModInt<I> {#[inline]fn modulus() -> u32 {Self::modulus()}#[inline]fn raw(val: u32) -> Self {Self::raw(val)}#[inline]fn val(self) -> u32 {self.val()}#[inline]fn inv(self) -> Self {self.inv()}}pub trait Id: 'static + Copy + Eq {fn companion_barrett() -> &'static Barrett;}#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]pub enum DefaultId {}impl Id for DefaultId {fn companion_barrett() -> &'static Barrett {static BARRETT: Barrett = Barrett::default();&BARRETT}}pub struct Barrett {m: AtomicU32,im: AtomicU64,}impl Barrett {#[inline]pub const fn new(m: u32) -> Self {Self {m: AtomicU32::new(m),im: AtomicU64::new((-1i64 as u64 / m as u64).wrapping_add(1)),}}#[inline]const fn default() -> Self {Self::new(998_244_353)}#[inline]fn update(&self, m: u32) {let im = (-1i64 as u64 / m as u64).wrapping_add(1);self.m.store(m, atomic::Ordering::SeqCst);self.im.store(im, atomic::Ordering::SeqCst);}#[inline]fn umod(&self) -> u32 {self.m.load(atomic::Ordering::SeqCst)}#[inline]fn mul(&self, a: u32, b: u32) -> u32 {let m = self.m.load(atomic::Ordering::SeqCst);let im = self.im.load(atomic::Ordering::SeqCst);internal_math::mul_mod(a, b, m, im)}}impl Default for Barrett {#[inline]fn default() -> Self {Self::default()}}pub trait ModIntBase:Default+ FromStr+ From<i8>+ From<i16>+ From<i32>+ From<i64>+ From<i128>+ From<isize>+ From<u8>+ From<u16>+ From<u32>+ From<u64>+ From<u128>+ From<usize>+ Copy+ Eq+ Hash+ fmt::Display+ fmt::Debug+ Neg<Output = Self>+ Add<Output = Self>+ Sub<Output = Self>+ Mul<Output = Self>+ Div<Output = Self>+ AddAssign+ SubAssign+ MulAssign+ DivAssign{fn modulus() -> u32;fn raw(val: u32) -> Self;fn val(self) -> u32;fn inv(self) -> Self;#[inline]fn new<T: RemEuclidU32>(val: T) -> Self {Self::raw(val.rem_euclid_u32(Self::modulus()))}#[inline]fn pow(self, mut n: u64) -> Self {let mut x = self;let mut r = Self::raw(1);while n > 0 {if n & 1 == 1 {r *= x;}x *= x;n >>= 1;}r}}pub trait RemEuclidU32 {fn rem_euclid_u32(self, modulus: u32) -> u32;}macro_rules! impl_rem_euclid_u32_for_small_signed {($($ty:tt),*) => {$(impl RemEuclidU32 for $ty {#[inline]fn rem_euclid_u32(self, modulus: u32) -> u32 {(self as i64).rem_euclid(i64::from(modulus)) as _}})*}}impl_rem_euclid_u32_for_small_signed!(i8, i16, i32, i64, isize);impl RemEuclidU32 for i128 {#[inline]fn rem_euclid_u32(self, modulus: u32) -> u32 {self.rem_euclid(i128::from(modulus)) as _}}macro_rules! impl_rem_euclid_u32_for_small_unsigned {($($ty:tt),*) => {$(impl RemEuclidU32 for $ty {#[inline]fn rem_euclid_u32(self, modulus: u32) -> u32 {self as u32 % modulus}})*}}macro_rules! impl_rem_euclid_u32_for_large_unsigned {($($ty:tt),*) => {$(impl RemEuclidU32 for $ty {#[inline]fn rem_euclid_u32(self, modulus: u32) -> u32 {(self % (modulus as $ty)) as _}})*}}impl_rem_euclid_u32_for_small_unsigned!(u8, u16, u32);impl_rem_euclid_u32_for_large_unsigned!(u64, u128);#[cfg(target_pointer_width = "32")]impl_rem_euclid_u32_for_small_unsigned!(usize);#[cfg(target_pointer_width = "64")]impl_rem_euclid_u32_for_large_unsigned!(usize);trait InternalImplementations: ModIntBase {#[inline]fn inv_for_non_prime_modulus(this: Self) -> Self {let (gcd, x) = internal_math::inv_gcd(this.val().into(), Self::modulus().into());if gcd != 1 {panic!("the multiplicative inverse does not exist");}Self::new(x)}#[inline]fn default_impl() -> Self {Self::raw(0)}#[inline]fn from_str_impl(s: &str) -> Result<Self, Infallible> {Ok(s.parse::<i64>().map(Self::new).unwrap_or_else(|_| todo!("parsing as an arbitrary precision integer?")))}#[inline]fn hash_impl(this: &Self, state: &mut impl Hasher) {this.val().hash(state)}#[inline]fn display_impl(this: &Self, f: &mut fmt::Formatter) -> fmt::Result {fmt::Display::fmt(&this.val(), f)}#[inline]fn debug_impl(this: &Self, f: &mut fmt::Formatter) -> fmt::Result {fmt::Debug::fmt(&this.val(), f)}#[inline]fn neg_impl(this: Self) -> Self {Self::sub_impl(Self::raw(0), this)}#[inline]fn add_impl(lhs: Self, rhs: Self) -> Self {let modulus = Self::modulus();let mut val = lhs.val() + rhs.val();if val >= modulus {val -= modulus;}Self::raw(val)}#[inline]fn sub_impl(lhs: Self, rhs: Self) -> Self {let modulus = Self::modulus();let mut val = lhs.val().wrapping_sub(rhs.val());if val >= modulus {val = val.wrapping_add(modulus)}Self::raw(val)}fn mul_impl(lhs: Self, rhs: Self) -> Self;#[inline]fn div_impl(lhs: Self, rhs: Self) -> Self {Self::mul_impl(lhs, rhs.inv())}}impl<M: Modulus> InternalImplementations for StaticModInt<M> {#[inline]fn mul_impl(lhs: Self, rhs: Self) -> Self {Self::raw((u64::from(lhs.val()) * u64::from(rhs.val()) % u64::from(M::VALUE)) as u32)}}impl<I: Id> InternalImplementations for DynamicModInt<I> {#[inline]fn mul_impl(lhs: Self, rhs: Self) -> Self {Self::raw(I::companion_barrett().mul(lhs.val, rhs.val))}}macro_rules! impl_basic_traits {() => {};(impl <$generic_param:ident : $generic_param_bound:tt> _ for $self:ty; $($rest:tt)*) => {impl <$generic_param: $generic_param_bound> Default for $self {#[inline]fn default() -> Self {Self::default_impl()}}impl <$generic_param: $generic_param_bound> FromStr for $self {type Err = Infallible;#[inline]fn from_str(s: &str) -> Result<Self, Infallible> {Self::from_str_impl(s)}}impl<$generic_param: $generic_param_bound, V: RemEuclidU32> From<V> for $self {#[inline]fn from(from: V) -> Self {Self::new(from)}}#[allow(clippy::derive_hash_xor_eq)]impl<$generic_param: $generic_param_bound> Hash for $self {#[inline]fn hash<H: Hasher>(&self, state: &mut H) {Self::hash_impl(self, state)}}impl<$generic_param: $generic_param_bound> fmt::Display for $self {#[inline]fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Self::display_impl(self, f)}}impl<$generic_param: $generic_param_bound> fmt::Debug for $self {#[inline]fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {Self::debug_impl(self, f)}}impl<$generic_param: $generic_param_bound> Neg for $self {type Output = $self;#[inline]fn neg(self) -> $self {Self::neg_impl(self)}}impl<$generic_param: $generic_param_bound> Neg for &'_ $self {type Output = $self;#[inline]fn neg(self) -> $self {<$self>::neg_impl(*self)}}impl_basic_traits!($($rest)*);};}impl_basic_traits! {impl <M: Modulus> _ for StaticModInt<M> ;impl <I: Id > _ for DynamicModInt<I>;}macro_rules! impl_bin_ops {() => {};(for<$($generic_param:ident : $generic_param_bound:tt),*> <$lhs_ty:ty> ~ <$rhs_ty:ty> -> $output:ty { { $lhs_body:expr } ~ { $rhs_body:expr } }$($rest:tt)*) => {impl <$($generic_param: $generic_param_bound),*> Add<$rhs_ty> for $lhs_ty {type Output = $output;#[inline]fn add(self, rhs: $rhs_ty) -> $output {<$output>::add_impl(apply($lhs_body, self), apply($rhs_body, rhs))}}impl <$($generic_param: $generic_param_bound),*> Sub<$rhs_ty> for $lhs_ty {type Output = $output;#[inline]fn sub(self, rhs: $rhs_ty) -> $output {<$output>::sub_impl(apply($lhs_body, self), apply($rhs_body, rhs))}}impl <$($generic_param: $generic_param_bound),*> Mul<$rhs_ty> for $lhs_ty {type Output = $output;#[inline]fn mul(self, rhs: $rhs_ty) -> $output {<$output>::mul_impl(apply($lhs_body, self), apply($rhs_body, rhs))}}impl <$($generic_param: $generic_param_bound),*> Div<$rhs_ty> for $lhs_ty {type Output = $output;#[inline]fn div(self, rhs: $rhs_ty) -> $output {<$output>::div_impl(apply($lhs_body, self), apply($rhs_body, rhs))}}impl_bin_ops!($($rest)*);};}macro_rules! impl_assign_ops {() => {};(for<$($generic_param:ident : $generic_param_bound:tt),*> <$lhs_ty:ty> ~= <$rhs_ty:ty> { _ ~= { $rhs_body:expr } } $($rest:tt)*) => {impl <$($generic_param: $generic_param_bound),*> AddAssign<$rhs_ty> for $lhs_ty {#[inline]fn add_assign(&mut self, rhs: $rhs_ty) {*self = *self + apply($rhs_body, rhs);}}impl <$($generic_param: $generic_param_bound),*> SubAssign<$rhs_ty> for $lhs_ty {#[inline]fn sub_assign(&mut self, rhs: $rhs_ty) {*self = *self - apply($rhs_body, rhs);}}impl <$($generic_param: $generic_param_bound),*> MulAssign<$rhs_ty> for $lhs_ty {#[inline]fn mul_assign(&mut self, rhs: $rhs_ty) {*self = *self * apply($rhs_body, rhs);}}impl <$($generic_param: $generic_param_bound),*> DivAssign<$rhs_ty> for $lhs_ty {#[inline]fn div_assign(&mut self, rhs: $rhs_ty) {*self = *self / apply($rhs_body, rhs);}}impl_assign_ops!($($rest)*);};}#[inline]fn apply<F: FnOnce(X) -> O, X, O>(f: F, x: X) -> O {f(x)}impl_bin_ops! {for<M: Modulus> <StaticModInt<M> > ~ <StaticModInt<M> > -> StaticModInt<M> { { |x| x } ~ { |x| x } }for<M: Modulus> <StaticModInt<M> > ~ <&'_ StaticModInt<M> > -> StaticModInt<M> { { |x| x } ~ { |&x| x } }for<M: Modulus> <&'_ StaticModInt<M> > ~ <StaticModInt<M> > -> StaticModInt<M> { { |&x| x } ~ { |x| x } }for<M: Modulus> <&'_ StaticModInt<M> > ~ <&'_ StaticModInt<M> > -> StaticModInt<M> { { |&x| x } ~ { |&x| x } }for<I: Id > <DynamicModInt<I> > ~ <DynamicModInt<I> > -> DynamicModInt<I> { { |x| x } ~ { |x| x } }for<I: Id > <DynamicModInt<I> > ~ <&'_ DynamicModInt<I>> -> DynamicModInt<I> { { |x| x } ~ { |&x| x } }for<I: Id > <&'_ DynamicModInt<I>> ~ <DynamicModInt<I> > -> DynamicModInt<I> { { |&x| x } ~ { |x| x } }for<I: Id > <&'_ DynamicModInt<I>> ~ <&'_ DynamicModInt<I>> -> DynamicModInt<I> { { |&x| x } ~ { |&x| x } }for<M: Modulus, T: RemEuclidU32> <StaticModInt<M> > ~ <T> -> StaticModInt<M> { { |x| x } ~ { StaticModInt::<M>::new } }for<I: Id , T: RemEuclidU32> <DynamicModInt<I> > ~ <T> -> DynamicModInt<I> { { |x| x } ~ { DynamicModInt::<I>::new } }}impl_assign_ops! {for<M: Modulus> <StaticModInt<M> > ~= <StaticModInt<M> > { _ ~= { |x| x } }for<M: Modulus> <StaticModInt<M> > ~= <&'_ StaticModInt<M> > { _ ~= { |&x| x } }for<I: Id > <DynamicModInt<I>> ~= <DynamicModInt<I> > { _ ~= { |x| x } }for<I: Id > <DynamicModInt<I>> ~= <&'_ DynamicModInt<I>> { _ ~= { |&x| x } }for<M: Modulus, T: RemEuclidU32> <StaticModInt<M> > ~= <T> { _ ~= { StaticModInt::<M>::new } }for<I: Id, T: RemEuclidU32> <DynamicModInt<I>> ~= <T> { _ ~= { DynamicModInt::<I>::new } }}macro_rules! impl_folding {() => {};(impl<$generic_param:ident : $generic_param_bound:tt> $trait:ident<_> for $self:ty { fn $method:ident(_) -> _ { _($unit:expr, $op:expr) } } $($rest:tt)*) => {impl<$generic_param: $generic_param_bound> $trait<Self> for $self {#[inline]fn $method<S>(iter: S) -> SelfwhereS: Iterator<Item = Self>,{iter.fold($unit, $op)}}impl<'a, $generic_param: $generic_param_bound> $trait<&'a Self> for $self {#[inline]fn $method<S>(iter: S) -> SelfwhereS: Iterator<Item = &'a Self>,{iter.fold($unit, $op)}}impl_folding!($($rest)*);};}impl_folding! {impl<M: Modulus> Sum<_> for StaticModInt<M> { fn sum(_) -> _ { _(Self::raw(0), Add::add) } }impl<M: Modulus> Product<_> for StaticModInt<M> { fn product(_) -> _ { _(Self::raw(1), Mul::mul) } }impl<I: Id > Sum<_> for DynamicModInt<I> { fn sum(_) -> _ { _(Self::raw(0), Add::add) } }impl<I: Id > Product<_> for DynamicModInt<I> { fn product(_) -> _ { _(Self::raw(1), Mul::mul) } }}}