結果
問題 | No.3123 Inversion |
ユーザー |
|
提出日時 | 2025-06-07 14:58:27 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 716 ms / 10,000 ms |
コード長 | 10,784 bytes |
コンパイル時間 | 12,321 ms |
コンパイル使用メモリ | 401,704 KB |
実行使用メモリ | 115,328 KB |
最終ジャッジ日時 | 2025-06-07 14:59:07 |
合計ジャッジ時間 | 35,952 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 21 |
ソースコード
#![allow(unused_imports,non_snake_case,dead_code)] use std::{cmp::Reverse as Rev,collections::*,iter::*}; use proconio::{marker::*,*}; #[fastout] fn main(){ input!{ t:usize, m:u32, case:[usize;t], } M::set_modulus(m); let M=|n:usize|M::new(n); let n=5e6 as usize+1; let mut fac=vec![M(0);n]; fac[0]+=1; for i in 1..n{ fac[i]=fac[i-1]*i; } let mut dp1=vec![M(0);n]; dp1[0]+=1; dp1[1]+=1; for i in 4..n{ if i%2==0{ dp1[i]=dp1[i-4]*(i-2); } else{ dp1[i]=dp1[i-4]*(i-3); } } let mut dp2=vec![M(0);n]; dp2[0]+=1; dp2[1]+=1; dp2[2]+=2; dp2[3]+=2; for i in 4..n{ if i%2==0{ dp2[i]=dp2[i-4]*(i-2)+dp2[i-2]*2; } else{ dp2[i]=dp2[i-4]*(i-3)+dp2[i-2]*2; } } let mut dp3=vec![M(0);n]; dp3[0]+=1; dp3[1]+=1; for i in 2..n{ dp3[i]=dp3[i-2]*(i/2)*2; } let mut dp4=vec![M(0);n]; dp4[0]+=1; dp4[1]+=1; for i in 2..n{ dp4[i]=dp4[i-1]+dp4[i-2]*(i-1); } let solve=|n:usize|->M{ if n==1{ return M(1); } // eprintln!("{}",dp1[n]); // eprintln!("{}",dp2[n]); // 位数4 let a=dp1[n]+dp2[n]; // 位数2 let b=dp3[n]-a+(dp4[n]-dp2[n])*2; // 位数1 let c=fac[n]-a-b; // eprintln!("{} {} {}",a,b,c); 2*a+4*b+8*c }; for &n in &case{ let ans=solve(n); println!("{ans}"); // break; } } // use std::collections::*; // use itertools::*; // use ac_library::*; // fn main(){ // let n=4; // let mut id=HashMap::new(); // let mut perm=vec![]; // for (i,p) in (0..n).permutations(n).enumerate(){ // perm.push(p.clone()); // id.insert(p,i); // } // let rev=|a:&[usize]|->Vec<usize>{ // (0..a.len()).rev().map(|i|a[i]).collect() // }; // let inv=|a:&[usize]|->Vec<usize>{ // let mut b=vec![!0;a.len()]; // for i in 0..a.len(){ // b[a[i]]=i; // } // b // }; // let mut uf=Dsu::new(id.len()); // for (i,p) in (0..n).permutations(n).enumerate(){ // let ni=id[&rev(&p)]; // uf.merge(i,ni); // let ni=id[&inv(&p)]; // uf.merge(i,ni); // } // let gs=uf.groups(); // // for i in 0..gs.len(){ // // if gs[i].len()==8{ // // for &id in &gs[i]{ // // eprintln!("{:?}",perm[id]); // // } // // } // // } // let mut cnt=[0;10]; // for i in 0..gs.len(){ // cnt[gs[i].len()]+=1; // } // for i in 0..cnt.len(){ // if cnt[i]!=0{ // println!("{}: {}",i,cnt[i]*i); // } // } // } // [2, 0, 1, 3] // [3, 1, 0, 2] type M=ModInt; type ModInt = DynamicModInt; static mut MODULO:u32=998244353; #[derive(Clone, Copy, PartialEq, Eq, Default, Hash)] struct DynamicModInt { val: u32, } impl DynamicModInt { fn set_modulus(m:u32) { unsafe{ MODULO = m } } } impl ModIntBase for DynamicModInt { fn modulus() -> u32 { unsafe{ MODULO } } unsafe fn raw(val: u32) -> Self { DynamicModInt { val } } fn val(self) -> u32 { self.val } fn inv(self) -> Self { assert!(self.val != 0, "divisor by zero"); let inv_val = mod_inv_by_ext_gcd(self.val, Self::modulus()); unsafe { Self::raw(inv_val) } } } impl std::fmt::Display for DynamicModInt { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.val) } } impl std::fmt::Debug for DynamicModInt { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.val) } } macro_rules! impl_from_int { ($($t:ty),*) => { $(impl From<$t> for DynamicModInt { fn from(x: $t) -> Self { DynamicModInt::new(x) } })* } } impl_from_int!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize); impl std::ops::Add for DynamicModInt { type Output = Self; fn add(self, rhs: Self) -> Self::Output { let mut sum = self.val + rhs.val; if sum >= Self::modulus() { sum -= Self::modulus(); } unsafe { Self::raw(sum) } } } impl std::ops::Sub for DynamicModInt { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { let diff = if self.val >= rhs.val { self.val - rhs.val } else { Self::modulus() + self.val - rhs.val }; unsafe { Self::raw(diff) } } } impl std::ops::Mul for DynamicModInt { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { let prod = (self.val as u64 * rhs.val as u64 % Self::modulus() as u64) as u32; unsafe { Self::raw(prod) } } } impl std::ops::Div for DynamicModInt { type Output = Self; fn div(self, rhs: Self) -> Self::Output { self * rhs.inv() } } impl std::ops::AddAssign for DynamicModInt { fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } } impl std::ops::SubAssign for DynamicModInt { fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } } impl std::ops::MulAssign for DynamicModInt { fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } } impl std::ops::DivAssign for DynamicModInt { fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; } } impl std::ops::Neg for DynamicModInt { type Output = Self; fn neg(self) -> Self::Output { if self.val == 0 { self } else { unsafe { Self::raw(Self::modulus() - self.val) } } } } impl std::str::FromStr for DynamicModInt { type Err = <u32 as std::str::FromStr>::Err; fn from_str(s: &str) -> Result<Self, Self::Err> { let x = s.parse::<u64>()?; Ok(DynamicModInt::new(x)) } } macro_rules! impl_mod_int_ops_sub { ($trait:ident, $func:ident, $assign_trait:ident, $assign_func:ident, $op:tt, ($($t:ty),*)) => { $( impl std::ops::$trait<$t> for DynamicModInt { type Output = Self; fn $func(self, rhs: $t) -> Self::Output { self $op DynamicModInt::new(rhs) } } impl std::ops::$trait<DynamicModInt> for $t { type Output = DynamicModInt; fn $func(self, rhs: DynamicModInt) -> Self::Output { DynamicModInt::new(self) $op rhs } } impl std::ops::$assign_trait<$t> for DynamicModInt { fn $assign_func(&mut self, rhs: $t) { *self = *self $op DynamicModInt::new(rhs); } } )* } } macro_rules! impl_mod_int_ops { ($($t:tt)*) => { impl_mod_int_ops_sub!($($t)*, (i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize)); } } impl_mod_int_ops!(Add, add, AddAssign, add_assign, +); impl_mod_int_ops!(Sub, sub, SubAssign, sub_assign, -); impl_mod_int_ops!(Mul, mul, MulAssign, mul_assign, *); impl_mod_int_ops!(Div, div, DivAssign, div_assign, /); impl std::iter::Sum for DynamicModInt { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { iter.fold(DynamicModInt::zero(), |acc, x| acc + x) } } impl std::iter::Product for DynamicModInt { fn product<I: Iterator<Item = Self>>(iter: I) -> Self { iter.fold(DynamicModInt::one(), |acc, x| acc * x) } } 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 { 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 { 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 { 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 { 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 ModIntBase: Default + std::str::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 + std::hash::Hash + std::fmt::Display + std::fmt::Debug + std::ops::Neg<Output = Self> + std::ops::Add<Output = Self> + std::ops::Sub<Output = Self> + std::ops::Mul<Output = Self> + std::ops::Div<Output = Self> + std::ops::AddAssign + std::ops::SubAssign + std::ops::MulAssign + std::ops::DivAssign { fn modulus() -> u32; unsafe fn raw(val: u32) -> Self; fn val(self) -> u32; fn inv(self) -> Self; fn new(val: impl RemEuclidU32) -> Self { unsafe { Self::raw(val.rem_euclid_u32(Self::modulus())) } } fn zero() -> Self { unsafe { Self::raw(0) } } fn one() -> Self { unsafe { Self::raw(1) } } fn pow(self, mut n: u64) -> Self { let mut x = self; let mut r = Self::one(); while n > 0 { if n & 1 == 1 { r *= x; } x *= x; n >>= 1; } r } } fn mod_inv_by_ext_gcd(x: u32, modulus: u32) -> u32 { let (mut a, mut b) = (x as i64, modulus as i64); let (mut u, mut v) = (1i64, 0i64); while b != 0 { let t = a / b; a -= t * b; (a,b)=(b,a); u -= t * v; (u,v)=(v,u); } assert!(a==1); ((u % modulus as i64 + modulus as i64) % modulus as i64) as u32 }