提出 #42175308
ソースコード 拡げる
use proconio::input;
use rustc_hash::FxHashMap;
fn main() {
input! {
n : usize,
m : usize,
s : [String; m]
}
let mut dp = FxHashMap::default();
dp.insert("".to_owned(), Mint::new(1));
for _ in 0..n.min(6) {
let mut next = FxHashMap::default();
for (k, &v) in dp.iter() {
for i in 0..2 {
let k = k.chars().rev().take(5).collect::<String>();
let k = k.chars().rev().collect::<String>();
let ns = k + if i==0 { "a" } else { "b" };
if s.iter().any(|s| {
let ns = ns.chars().rev().take(s.len()).collect::<String>();
let ns = ns.chars().rev().collect::<String>();
&ns == s
}) { continue; }
*next.entry(ns).or_insert(Mint::new(0)) += v;
}
}
dp = next;
}
if n <= 6 {
println!("{}", dp.iter().fold(Mint::new(0), |acc, (_, x)| acc + x));
return;
}
let mut v = vec![Mint::new(0); 1<<6];
let mut mat = matrix::Matrix::new(1<<6, 1<<6, Mint::new(0));
for (k, &val) in dp.iter() {
let k = k.chars().fold(0, |acc, c| acc * 2 + if c=='a' { 0 } else { 1 });
v[k] += val;
for i in 0..2 {
let l = (k * 2 + i) & 0b111111;
mat[k][l] += 1;
}
}
let t = mat.pow(n - 6, Mint::new(1));
let ans = t * &v;
println!("{}", ans.iter().sum::<Mint>());
}
#[allow(dead_code)]
pub mod matrix {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Matrix<T>(pub Vec<Vec<T>>);
impl<T: Clone + Copy> Matrix<T> {
pub fn new(n: usize, m: usize, v: T) -> Self {
Self(vec![vec![v; m]; n])
}
pub fn identity(n: usize, id:T) -> Self where T: Default {
let mut mat = Self::new(n, n, T::default());
for i in 0..n { mat[i][i] = id; }
mat
}
pub fn pow(&self, mut n: usize, id:T) -> Self where T: Default + std::ops::Mul<Output=T> + std::ops::AddAssign {
let mut a = self.clone();
let mut b = Self::identity(a.0.len(), id);
while n > 0 {
if n & 1 == 1 { b = b * &a; }
a = &a * &a;
n >>= 1;
}
b
}
}
impl<T: Clone + Copy + std::ops::Mul<Output=T> + std::ops::AddAssign + Default> std::ops::Mul for &Matrix<T> {
type Output = Matrix<T>;
fn mul(self, rhs: Self) -> Self::Output {
let mut mat = Matrix::new(self.0.len(), rhs.0[0].len(), T::default());
for i in 0..self.0.len() {
for j in 0..rhs.0[0].len() {
for k in 0..self.0[0].len() {
mat[i][j] += self.0[i][k].clone() * rhs.0[k][j].clone();
}
}
}
mat
}
}
impl<T: Clone + Copy + std::ops::Mul<Output=T> + std::ops::AddAssign + Default, Rhs: std::borrow::Borrow<Matrix<T>>> std::ops::Mul<Rhs> for Matrix<T> {
type Output = Self;
fn mul(self, rhs: Rhs) -> Self {
let rhs = rhs.borrow();
let mut mat = Self::new(self.0.len(), rhs.0[0].len(), T::default());
for i in 0..self.0.len() {
for j in 0..rhs.0[0].len() {
for k in 0..self.0[0].len() {
mat[i][j] += self.0[i][k].clone() * rhs.0[k][j].clone();
}
}
}
mat
}
}
impl<T> std::ops::Index<usize> for Matrix<T> {
type Output = Vec<T>;
fn index(&self, i: usize) -> &Self::Output {
&self.0[i]
}
}
impl<T> std::ops::IndexMut<usize> for Matrix<T> {
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
&mut self.0[i]
}
}
impl<T: Clone + Copy + std::ops::AddAssign + std::ops::Mul<Output=T> + Default> std::ops::Mul<Vec<T>> for Matrix<T> {
type Output = Vec<T>;
fn mul(self, rhs: Vec<T>) -> Self::Output {
let mut v = vec![T::default(); self.0.len()];
for i in 0..self.0.len() {
for j in 0..rhs.len() {
v[i] += self.0[i][j].clone() * rhs[j].clone();
}
}
v
}
}
impl<T: Clone + Copy + std::ops::AddAssign + std::ops::Mul<Output=T> + Default> std::ops::Mul<&Vec<T>> for Matrix<T> {
type Output = Vec<T>;
fn mul(self, rhs: &Vec<T>) -> Self::Output {
let mut v = vec![T::default(); self.0.len()];
for i in 0..self.0.len() {
for j in 0..rhs.len() {
v[i] += self.0[i][j].clone() * rhs[j].clone();
}
}
v
}
}
impl<T: Clone + Copy + std::ops::AddAssign + std::ops::Mul<Output=T> + Default> std::ops::Mul<Vec<T>> for &Matrix<T> {
type Output = Vec<T>;
fn mul(self, rhs: Vec<T>) -> Self::Output {
let mut v = vec![T::default(); self.0.len()];
for i in 0..self.0.len() {
for j in 0..rhs.len() {
v[i] += self.0[i][j].clone() * rhs[j].clone();
}
}
v
}
}
impl<T: Clone + Copy + std::ops::AddAssign + std::ops::Mul<Output=T> + Default> std::ops::Mul<&Vec<T>> for &Matrix<T> {
type Output = Vec<T>;
fn mul(self, rhs: &Vec<T>) -> Self::Output {
let mut v = vec![T::default(); self.0.len()];
for i in 0..self.0.len() {
for j in 0..rhs.len() {
v[i] += self.0[i][j].clone() * rhs[j].clone();
}
}
v
}
}
}
type Mint = ModInt998244353;
pub mod internal_math { #![allow(dead_code)] use std::mem::swap; 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 } #[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 } 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 } #[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; swap(&mut s, &mut t); swap(&mut m0, &mut m1); } if m0 < 0 { m0 += b / s; } (s, m0) } 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; } }}
#[allow(dead_code)]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) -> Self where S: 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) -> Self where S: 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) } } }}
use modint::*;
提出情報
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
550 / 550 |
| 結果 |
|
|
| セット名 |
テストケース |
| Sample |
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt |
| All |
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 01_random_10.txt, 01_random_11.txt, 01_random_12.txt, 02_max_13.txt, 02_max_14.txt, 02_max_15.txt, 02_max_16.txt, 02_max_17.txt, 02_max_18.txt, 02_max_19.txt, 02_max_20.txt, 02_max_21.txt, 02_max_22.txt, 03_handmade_23.txt, 03_handmade_24.txt, 03_handmade_25.txt, 03_handmade_26.txt, 03_handmade_27.txt, 03_handmade_28.txt, 03_handmade_29.txt, 03_handmade_30.txt, 03_handmade_31.txt, 04_small_32.txt, 04_small_33.txt, 04_small_34.txt, 04_small_35.txt, 04_small_36.txt, 04_small_37.txt, 04_small_38.txt, 04_small_39.txt, 04_small_40.txt, 04_small_41.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 00_sample_00.txt |
AC |
7 ms |
2152 KiB |
| 00_sample_01.txt |
AC |
15 ms |
2172 KiB |
| 00_sample_02.txt |
AC |
45 ms |
2144 KiB |
| 01_random_03.txt |
AC |
72 ms |
2072 KiB |
| 01_random_04.txt |
AC |
77 ms |
2152 KiB |
| 01_random_05.txt |
AC |
75 ms |
2208 KiB |
| 01_random_06.txt |
AC |
71 ms |
2164 KiB |
| 01_random_07.txt |
AC |
77 ms |
2220 KiB |
| 01_random_08.txt |
AC |
78 ms |
2188 KiB |
| 01_random_09.txt |
AC |
73 ms |
2252 KiB |
| 01_random_10.txt |
AC |
72 ms |
2140 KiB |
| 01_random_11.txt |
AC |
81 ms |
2188 KiB |
| 01_random_12.txt |
AC |
73 ms |
2136 KiB |
| 02_max_13.txt |
AC |
76 ms |
2156 KiB |
| 02_max_14.txt |
AC |
77 ms |
2184 KiB |
| 02_max_15.txt |
AC |
78 ms |
2080 KiB |
| 02_max_16.txt |
AC |
80 ms |
2180 KiB |
| 02_max_17.txt |
AC |
79 ms |
2192 KiB |
| 02_max_18.txt |
AC |
78 ms |
2076 KiB |
| 02_max_19.txt |
AC |
77 ms |
2200 KiB |
| 02_max_20.txt |
AC |
80 ms |
2152 KiB |
| 02_max_21.txt |
AC |
77 ms |
2220 KiB |
| 02_max_22.txt |
AC |
78 ms |
2176 KiB |
| 03_handmade_23.txt |
AC |
2 ms |
2152 KiB |
| 03_handmade_24.txt |
AC |
4 ms |
2080 KiB |
| 03_handmade_25.txt |
AC |
72 ms |
2172 KiB |
| 03_handmade_26.txt |
AC |
75 ms |
2192 KiB |
| 03_handmade_27.txt |
AC |
70 ms |
2100 KiB |
| 03_handmade_28.txt |
AC |
80 ms |
2220 KiB |
| 03_handmade_29.txt |
AC |
78 ms |
2224 KiB |
| 03_handmade_30.txt |
AC |
71 ms |
2152 KiB |
| 03_handmade_31.txt |
AC |
70 ms |
2140 KiB |
| 04_small_32.txt |
AC |
2 ms |
2008 KiB |
| 04_small_33.txt |
AC |
1 ms |
2056 KiB |
| 04_small_34.txt |
AC |
7 ms |
2156 KiB |
| 04_small_35.txt |
AC |
1 ms |
2096 KiB |
| 04_small_36.txt |
AC |
1 ms |
2032 KiB |
| 04_small_37.txt |
AC |
10 ms |
2228 KiB |
| 04_small_38.txt |
AC |
1 ms |
2108 KiB |
| 04_small_39.txt |
AC |
1 ms |
2152 KiB |
| 04_small_40.txt |
AC |
3 ms |
2064 KiB |
| 04_small_41.txt |
AC |
1 ms |
2008 KiB |