結果
問題 | No.732 3PrimeCounting |
ユーザー | へのく |
提出日時 | 2021-06-22 20:52:55 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 491 ms / 3,000 ms |
コード長 | 42,553 bytes |
コンパイル時間 | 17,308 ms |
コンパイル使用メモリ | 378,164 KB |
実行使用メモリ | 19,440 KB |
最終ジャッジ日時 | 2024-06-23 16:59:28 |
合計ジャッジ時間 | 25,966 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,248 KB |
testcase_03 | AC | 1 ms
5,248 KB |
testcase_04 | AC | 1 ms
5,248 KB |
testcase_05 | AC | 0 ms
5,248 KB |
testcase_06 | AC | 1 ms
5,376 KB |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 1 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | AC | 1 ms
5,376 KB |
testcase_11 | AC | 1 ms
5,376 KB |
testcase_12 | AC | 1 ms
5,376 KB |
testcase_13 | AC | 1 ms
5,376 KB |
testcase_14 | AC | 1 ms
5,376 KB |
testcase_15 | AC | 1 ms
5,376 KB |
testcase_16 | AC | 1 ms
5,376 KB |
testcase_17 | AC | 1 ms
5,376 KB |
testcase_18 | AC | 1 ms
5,376 KB |
testcase_19 | AC | 0 ms
5,376 KB |
testcase_20 | AC | 3 ms
5,376 KB |
testcase_21 | AC | 8 ms
5,376 KB |
testcase_22 | AC | 8 ms
5,376 KB |
testcase_23 | AC | 1 ms
5,376 KB |
testcase_24 | AC | 1 ms
5,376 KB |
testcase_25 | AC | 15 ms
5,376 KB |
testcase_26 | AC | 13 ms
5,376 KB |
testcase_27 | AC | 4 ms
5,376 KB |
testcase_28 | AC | 4 ms
5,376 KB |
testcase_29 | AC | 7 ms
5,376 KB |
testcase_30 | AC | 6 ms
5,376 KB |
testcase_31 | AC | 8 ms
5,376 KB |
testcase_32 | AC | 12 ms
5,376 KB |
testcase_33 | AC | 13 ms
5,376 KB |
testcase_34 | AC | 13 ms
5,376 KB |
testcase_35 | AC | 13 ms
5,376 KB |
testcase_36 | AC | 13 ms
5,376 KB |
testcase_37 | AC | 2 ms
5,376 KB |
testcase_38 | AC | 2 ms
5,376 KB |
testcase_39 | AC | 12 ms
5,376 KB |
testcase_40 | AC | 8 ms
5,376 KB |
testcase_41 | AC | 7 ms
5,376 KB |
testcase_42 | AC | 8 ms
5,376 KB |
testcase_43 | AC | 7 ms
5,376 KB |
testcase_44 | AC | 8 ms
5,376 KB |
testcase_45 | AC | 4 ms
5,376 KB |
testcase_46 | AC | 5 ms
5,376 KB |
testcase_47 | AC | 6 ms
5,376 KB |
testcase_48 | AC | 15 ms
5,376 KB |
testcase_49 | AC | 15 ms
5,376 KB |
testcase_50 | AC | 8 ms
5,376 KB |
testcase_51 | AC | 8 ms
5,376 KB |
testcase_52 | AC | 3 ms
5,376 KB |
testcase_53 | AC | 32 ms
5,376 KB |
testcase_54 | AC | 237 ms
11,276 KB |
testcase_55 | AC | 238 ms
11,272 KB |
testcase_56 | AC | 239 ms
11,400 KB |
testcase_57 | AC | 69 ms
5,376 KB |
testcase_58 | AC | 67 ms
5,376 KB |
testcase_59 | AC | 32 ms
5,376 KB |
testcase_60 | AC | 114 ms
6,068 KB |
testcase_61 | AC | 113 ms
6,064 KB |
testcase_62 | AC | 241 ms
12,556 KB |
testcase_63 | AC | 140 ms
7,680 KB |
testcase_64 | AC | 116 ms
6,648 KB |
testcase_65 | AC | 114 ms
6,640 KB |
testcase_66 | AC | 1 ms
5,376 KB |
testcase_67 | AC | 1 ms
5,376 KB |
testcase_68 | AC | 241 ms
12,068 KB |
testcase_69 | AC | 238 ms
12,064 KB |
testcase_70 | AC | 236 ms
11,320 KB |
testcase_71 | AC | 236 ms
11,320 KB |
testcase_72 | AC | 140 ms
7,400 KB |
testcase_73 | AC | 294 ms
15,376 KB |
testcase_74 | AC | 300 ms
15,380 KB |
testcase_75 | AC | 15 ms
5,376 KB |
testcase_76 | AC | 235 ms
11,724 KB |
testcase_77 | AC | 68 ms
5,376 KB |
testcase_78 | AC | 288 ms
13,788 KB |
testcase_79 | AC | 236 ms
11,988 KB |
testcase_80 | AC | 285 ms
13,080 KB |
testcase_81 | AC | 236 ms
11,492 KB |
testcase_82 | AC | 3 ms
5,376 KB |
testcase_83 | AC | 66 ms
5,376 KB |
testcase_84 | AC | 110 ms
5,704 KB |
testcase_85 | AC | 229 ms
10,700 KB |
testcase_86 | AC | 285 ms
13,432 KB |
testcase_87 | AC | 491 ms
19,440 KB |
testcase_88 | AC | 488 ms
19,440 KB |
ソースコード
#![allow(non_snake_case)] use crate::{ fps::{conv_i64::ConvI64, formal_power_series::Fps}, primes::utils::sieve, scanner::Scanner, }; fn main() { let mut scan = Scanner::new(); let n = scan.int(); let (primes, _) = sieve(3 * n); let mut ret = 0i64; let f = Fps::<i64, ConvI64>::new_degs(&primes.take_while(|&p| p <= n)); let mut g = &f * &f * &f; g.resize(3 * n + 1); ret += primes.map(|p| g[p]).sum(); let mut g = Fps::new_degs(&primes.take_while(|&p| p <= n).map(|p| p * 2)); g *= &f; g.resize(3 * n + 1); ret -= 3 * primes.map(|p| g[p]).sum(); println!("{}", ret / 6); } pub mod primes { pub mod utils { use crate::arraylist::List; pub fn sieve(n: isize) -> (List<isize>, List<bool>) { let mut primes = List::new(); let mut is_prime = List::init(true, n + 1); is_prime.fill(0..=1, false); for i in 2..n + 1 { if is_prime[i] { primes.push(i); for j in (2..).map(|j| j * i).take_while(|&j| j <= n) { is_prime[j] = false; } } } (primes, is_prime) } } } pub mod scanner { use std::io::{stdin, BufReader, Bytes, Read, Stdin}; use std::str::FromStr; pub struct Scanner { buf: Bytes<BufReader<Stdin>>, } impl Scanner { pub fn new() -> Scanner { Scanner { buf: BufReader::new(stdin()).bytes(), } } #[inline] fn token<T: std::iter::FromIterator<char>>(&mut self) -> T { self.buf .by_ref() .map(|c| c.unwrap() as char) .skip_while(|c| c.is_whitespace()) .take_while(|c| !c.is_whitespace()) .collect() } #[inline] pub fn read<T: FromStr>(&mut self) -> T { self.string().parse().ok().unwrap() } #[inline] pub fn string(&mut self) -> String { self.token() } #[inline] pub fn int(&mut self) -> isize { self.read() } } } pub mod nums { use std::mem::swap; pub fn ceil_pow2(n: u32) -> u32 { 32 - n.saturating_sub(1).leading_zeros() } pub fn inv_gcd(a: i64, b: i64) -> (i64, i64) { let a = a.rem_euclid(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 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 as _, ((m - 1) / divs[i]) as _, m as _) != 1) { break g as i32; } g += 1; } } pub fn pow_mod(mut a: i64, mut n: i64, m: i64) -> i64 { let mut res = 1; a %= m; while n > 0 { if n & 1 == 1 { res *= a; res %= m; } a = (a * a) % m; n >>= 1; } res } } pub mod modulo { use crate::nums::inv_gcd; use crate::{impl_integer_functions, independent::integer::Int}; use std::cell::RefCell; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::*; use std::sync::atomic::{self, AtomicU32}; use std::thread::LocalKey; pub trait Modulus: 'static + PartialEq + Eq + Copy + Clone + std::hash::Hash + Ord { const M: u32; const HINT_M_IS_PRIME: bool; fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>>; } pub trait DynamicModulus: 'static + PartialEq + Eq + Copy + Clone + std::hash::Hash + Ord { fn state() -> &'static AtomicU32 { static M: AtomicU32 = AtomicU32::new(1_000_000_007); &M } fn update(m: u32) { Self::state().store(m, atomic::Ordering::SeqCst) } fn umod() -> u32 { Self::state().load(atomic::Ordering::SeqCst) } } #[derive(PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)] pub enum DefaultId {} impl DynamicModulus for DefaultId {} macro_rules! impl_from_for_modint { ($name:ident, $guard: ident, $($tpe:ident),*) => { $( impl<T: $guard> From<$tpe> for $name<T> { fn from(n: $tpe) -> Self { Self::new(n) } } )* }; } macro_rules! impl_assign { ($name:ident, $guard:ident, $($t1:ty, $t2:ty, $fa:ident, $f:ident),*) => { $( impl<T: $guard> $t1 for $name<T> { type Output = Self; #[inline] fn $f(self, other: Self) -> Self { <Self as ModInt>::$f(self, other) } } impl<T: $guard> $t2 for $name<T> { #[inline] fn $fa(&mut self, other: Self) { *self = <Self as ModInt>::$f(*self, other); } } )* }; } macro_rules! impl_modint_structs { ($name:ident, $guard:ident) => { #[derive(PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)] #[repr(transparent)] pub struct $name<T> { pub val: u32, phantom: PhantomData<fn() -> T>, } impl<T> Debug for $name<T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.val.fmt(f) } } impl<T: $guard> $name<T> { #[inline] pub fn new<U: Int>(a: U) -> Self { <Self as ModInt>::new(a) } #[inline] pub fn inv(self) -> Self { <Self as ModInt>::inv(self) } #[inline] pub fn raw(val: u32) -> Self { Self { val, phantom: PhantomData, } } #[inline] pub fn pow<U: Int>(self, x: U) -> Self { <Self as ModInt>::pow(self, x) } #[inline] pub fn zero() -> Self { <Self as Int>::zero() } #[inline] pub fn one() -> Self { <Self as Int>::one() } } impl<T> std::fmt::Display for $name<T> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.val) } } impl_from_for_modint!( $name, $guard, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize ); impl_assign!( $name, $guard, Add, AddAssign, add_assign, add, Sub, SubAssign, sub_assign, sub, Mul, MulAssign, mul_assign, mul, Div, DivAssign, div_assign, div, Rem, RemAssign, rem_assign, rem ); impl<T: $guard> Int for $name<T> { impl_integer_functions!(|s: &Self| s.val, |x| Self::new(x), |s: &Self, n: i64| s .pow(n)); } }; } impl_modint_structs!(StaticModInt, Modulus); impl_modint_structs!(DynamicModInt, DynamicModulus); #[macro_export] macro_rules! modint { () => {$crate::modint!(1000000007, true);}; ($m:literal) => {$crate::modint!($m, true);}; ($m:literal, $is_prime:literal) => { $crate::modint!($m, ModValue, $is_prime); #[allow(dead_code)] type Z = $crate::modulo::StaticModInt<ModValue>; }; ($name:ident) => { $crate::modint!($name, $name, true); }; ($value:expr, $name:ident, $is_prime:literal) => { #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)] pub enum $name {} impl $crate::modulo::Modulus for $name { const M: u32 = $value as _; const HINT_M_IS_PRIME: bool = $is_prime; fn butterfly_cache() -> &'static ::std::thread::LocalKey<::std::cell::RefCell<::std::option::Option<$crate::modulo::ButterflyCache<Self>>>> { thread_local! { static BUTTERFLY_CACHE: ::std::cell::RefCell<::std::option::Option<$crate::modulo::ButterflyCache<$name>>> = ::std::default::Default::default(); } &BUTTERFLY_CACHE } } }; } pub type D = DynamicModInt<DefaultId>; pub trait ModInt: Int { fn new<U: Int>(val: U) -> Self { let x = val.to_i128(); Self::raw(x.rem_euclid(Self::modulus() as i128) as _) } fn inv(self) -> Self { if Self::mod_is_prime() { Self::pow(self, Self::modulus() - 2) } else { let (g, x) = inv_gcd(Self::val(self) as _, Self::modulus() as _); if g != 1 { panic!("the multiplicative inverse does not exist"); } else { Self::new(x) } } } fn raw(val: u32) -> Self; fn val(self) -> u32; fn modulus() -> u32; fn mod_is_prime() -> bool; fn add(self, other: Self) -> Self { let mut ret = self.val() + other.val(); if ret >= Self::modulus() { ret -= Self::modulus(); } Self::raw(ret) } fn sub(self, other: Self) -> Self { let mut ret = self.val().wrapping_sub(other.val()); if ret >= Self::modulus() { ret = ret.wrapping_add(Self::modulus()); } Self::raw(ret) } fn mul(self, other: Self) -> Self { Self::raw( (u64::from(self.val()) * u64::from(other.val()) % u64::from(Self::modulus())) as _, ) } fn div(self, other: Self) -> Self { self * other.inv() } fn rem(self, other: Self) -> Self { Self::raw(self.val() % other.val()) } fn pow<U: Int>(self, x: U) -> Self { let mut n = x.to_i64(); let mut a = self; let mut res = Self::raw(1); while n > 0 { if n & 1 == 1 { res *= a; } a = a * a; n >>= 1; } res } } impl<M: Modulus> ModInt for StaticModInt<M> { fn raw(val: u32) -> Self { Self::raw(val) } fn val(self) -> u32 { self.val } fn modulus() -> u32 { M::M } fn mod_is_prime() -> bool { M::HINT_M_IS_PRIME } } impl<M: DynamicModulus> ModInt for DynamicModInt<M> { fn raw(val: u32) -> Self { Self::raw(val) } fn val(self) -> u32 { self.val } fn modulus() -> u32 { M::umod() } fn mod_is_prime() -> bool { false } } pub struct ButterflyCache<T> { pub sum_e: Vec<StaticModInt<T>>, pub sum_ie: Vec<StaticModInt<T>>, } } pub mod fps { pub mod convolution { use crate::{ arraylist::List, independent::integer::Int, modint, modulo::{ButterflyCache, Modulus, StaticModInt}, nums::*, }; fn prepare<M: Modulus>() -> ButterflyCache<M> { let g = StaticModInt::<M>::raw(primitive_root(M::M as i32) as u32); let mut es = [StaticModInt::<M>::raw(0); 30]; let mut ies = [StaticModInt::<M>::raw(0); 30]; let cnt2 = (M::M - 1).trailing_zeros() as usize; let mut e = g.pow((M::M - 1) >> cnt2); let mut ie = e.inv(); for i in (2..=cnt2).rev() { es[i - 2] = e; ies[i - 2] = ie; e *= e; ie *= ie; } let sum_e = es .iter() .scan(StaticModInt::new(1), |acc, e| { *acc *= *e; Some(*acc) }) .collect(); let sum_ie = ies .iter() .scan(StaticModInt::new(1), |acc, ie| { *acc *= *ie; Some(*acc) }) .collect(); ButterflyCache { sum_e, sum_ie } } fn butterfly<M: Modulus>(a: &mut [StaticModInt<M>]) { let n = a.len(); let h = ceil_pow2(n as u32); M::butterfly_cache().with(|cache| { let mut cache = cache.borrow_mut(); let ButterflyCache { sum_e, .. } = cache.get_or_insert_with(prepare); for ph in 1..=h { let w = 1 << (ph - 1); let p = 1 << (h - ph); let mut now = StaticModInt::<M>::new(1); for s in 0..w { let offset = s << (h - ph + 1); for i in 0..p { let l = a[i + offset]; let r = a[i + offset + p] * now; a[i + offset] = l + r; a[i + offset + p] = l - r; } now *= sum_e[(!s).trailing_zeros() as usize]; } } }); } fn butterfly_inv<M: Modulus>(a: &mut [StaticModInt<M>]) { let n = a.len(); let h = ceil_pow2(n as u32); M::butterfly_cache().with(|cache| { let mut cache = cache.borrow_mut(); let ButterflyCache { sum_ie, .. } = cache.get_or_insert_with(prepare); for ph in (1..=h).rev() { let w = 1 << (ph - 1); let p = 1 << (h - ph); let mut inow = StaticModInt::<M>::new(1); for s in 0..w { let offset = s << (h - ph + 1); for i in 0..p { let l = a[i + offset]; let r = a[i + offset + p]; a[i + offset] = l + r; a[i + offset + p] = StaticModInt::new(M::M + l.val - r.val) * inow; } inow *= sum_ie[(!s).trailing_zeros() as usize]; } } }) } pub fn convolution_naive<T: Int>(a: &[T], b: &[T]) -> List<T> { if a.is_empty() || b.is_empty() { return vec![].into(); } let (n, m) = (a.len(), b.len()); let (n, m, a, b) = if n < m { (m, n, b, a) } else { (n, m, a, b) }; let mut ans = vec![T::zero(); n + m - 1]; for i in 0..n { for j in 0..m { ans[i + j] += a[i] * b[j]; } } ans.into() } pub fn convolution_ntt<M: Modulus>( a: &[StaticModInt<M>], b: &[StaticModInt<M>], ) -> List<StaticModInt<M>> { if a.is_empty() || b.is_empty() { return vec![].into(); } let (n, m) = (a.len(), b.len()); if n.min(m) <= 60 { return convolution_naive(a, b); } let (mut a, mut b) = (a.to_owned(), b.to_owned()); let z = 1 << ceil_pow2((n + m - 1) as _); a.resize(z, StaticModInt::raw(0)); butterfly(&mut a); b.resize(z, StaticModInt::raw(0)); butterfly(&mut b); for (a, b) in a.iter_mut().zip(&b) { *a *= *b; } butterfly_inv(&mut a); a.resize(n + m - 1, StaticModInt::raw(0)); let iz = StaticModInt::new(z).inv(); for a in &mut a { *a *= iz; } a.into() } fn convolution_raw<T: Int, M: Modulus>(a: &[T], b: &[T]) -> List<T> { convolution_raw_mod::<T, M>(&a, &b) .into_iter() .map(|z| T::from_u32(z.val)) .collect() } fn convolution_raw_mod<T: Int, M: Modulus>(a: &[T], b: &[T]) -> List<StaticModInt<M>> { let a = a .iter() .cloned() .map(StaticModInt::<M>::new) .collect::<Vec<_>>(); let b = b .iter() .cloned() .map(StaticModInt::<M>::new) .collect::<Vec<_>>(); convolution_ntt::<M>(&a, &b) } pub fn convolution_i64(a: &[i64], b: &[i64]) -> List<i64> { const M1: u64 = 754_974_721; const M2: u64 = 167_772_161; const M3: u64 = 469_762_049; const M2M3: u64 = M2 * M3; const M1M3: u64 = M1 * M3; const M1M2: u64 = M1 * M2; const M1M2M3: u64 = M1M2.wrapping_mul(M3); modint!(M1); modint!(M2); modint!(M3); if a.is_empty() || b.is_empty() { return List::new(); } let (_, i1) = inv_gcd(M2M3 as _, M1 as _); let (_, i2) = inv_gcd(M1M3 as _, M2 as _); let (_, i3) = inv_gcd(M1M2 as _, M3 as _); let c1 = convolution_raw::<_, M1>(a, b); let c2 = convolution_raw::<_, M2>(a, b); let c3 = convolution_raw::<_, M3>(a, b); c1.into_iter() .zip(c2) .zip(c3) .map(|((c1, c2), c3)| { const OFFSET: &[u64] = &[0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3]; let mut x = [(c1, i1, M1, M2M3), (c2, i2, M2, M1M3), (c3, i3, M3, M1M2)] .iter() .map(|&(c, i, m1, m2)| { c.wrapping_mul(i).rem_euclid(m1 as _).wrapping_mul(m2 as _) }) .fold(0, i64::wrapping_add); let mut diff = c1 - x.rem_euclid(M1 as _); if diff < 0 { diff += M1 as i64; } x = x.wrapping_sub(OFFSET[diff.rem_euclid(5) as usize] as _); x }) .collect() } } pub mod conv_i64 { use crate::{ arraylist::List, fps::{convolution::convolution_i64, formal_power_series::Conv}, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)] pub enum ConvI64 {} impl Conv<i64> for ConvI64 { fn convolution(a: &[i64], b: &[i64]) -> List<i64> { convolution_i64(a, b) } } #[macro_export] macro_rules! fps_i64 { ($($args:tt)+) => {$crate::fps!([$($args)+] [$crate::fps::conv_i64::ConvI64])}; } } pub mod formal_power_series { use std::{fmt::Debug, iter::FromIterator, marker::PhantomData, ops::*}; use crate::{ arraylist::{lst, List}, independent::integer::Int, list, modulo::ModInt, }; pub trait Conv<T> { fn convolution(a: &[T], b: &[T]) -> List<T>; } impl<T: Int, F: Conv<T>> From<&lst<T>> for Fps<T, F> { fn from(lst: &lst<T>) -> Self { Self::new(lst.list()) } } impl<T: Int, F: Conv<T>> FromIterator<T> for Fps<T, F> { fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self { Self::new(iter.into_iter().collect()) } } #[derive(PartialEq, Eq)] pub struct Fps<T, F: Conv<T>> { pub data: List<T>, phantom: PhantomData<fn() -> F>, } impl<T: Int, F: Conv<T>> Clone for Fps<T, F> { fn clone(&self) -> Self { Self::new(self.data.clone()) } } impl<T: Int + Debug, F: Conv<T>> Debug for Fps<T, F> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.data.fmt(f) } } impl<T: Int, F: Conv<T>> Fps<T, F> { pub fn new(data: List<T>) -> Fps<T, F> { Fps { data, phantom: PhantomData, } } pub fn new_degs(degrees: &lst<isize>) -> Fps<T, F> { degrees .hist(degrees.max_item().map_or(0, |m| *m + 1)) .into_iter() .map(T::from_isize) .collect() } pub fn empty() -> Self { Self::new(List::new()) } pub fn lens(&self) -> isize { self.data.lens() } pub fn is_empty(&self) -> bool { self.data.lens() == 0 } pub fn resize(&mut self, new_len: isize) { self.data.resize(new_len, T::zero()); } pub fn shrink(&mut self) { while self.data.last() == Some(&T::zero()) { self.data.pop(); } } pub fn pre(&self, size: isize) -> Self { Self::from(&self.data[..self.lens().min(size)]) } pub fn inv(&self, deg: impl Into<Option<isize>>) -> Self where T: ModInt, { assert!(self[0] != T::zero()); let n = self.lens(); let deg = deg.into().unwrap_or(n); let mut ret = Self::new(list![T::one() / self[0]]); let mut i = 1; while i < deg { ret = (&ret + &ret - &ret * &ret * &self.pre(i << 1)).pre(i << 1); i <<= 1; } ret.pre(deg) } } macro_rules! impl_ops { ($({$guard:ident, $tpe:ident, $fname:ident, $op:tt, [$($lhs:tt)+], [$($rhs:tt)+]})*) => { $(impl<T: $guard, F: Conv<T>> $tpe<$($rhs)+> for $($lhs)+ { type Output = Fps<T, F>; fn $fname(self, rhs: $($rhs)+) -> Self::Output { let mut ret: Fps<T, F> = self.clone(); ret $op rhs; ret } })* }; } macro_rules! impl_ops_times { ($([$($lhs:tt)+] * [$($rhs:tt)+]),*; $([$($lhs2:tt)+] * [$($rhs2:tt)+]),*) => { $( impl_ops!( {Int, Add, add, +=, [$($lhs)+], [$($rhs)+]} {Int, Sub, sub, -=, [$($lhs)+], [$($rhs)+]} {Int, Mul, mul, *=, [$($lhs)+], [$($rhs)+]} {ModInt, Div, div, /=, [$($lhs)+], [$($rhs)+]} {ModInt, Rem, rem, %=, [$($lhs)+], [$($rhs)+]} ); )* $( impl_ops!( {Int, Add, add, +=, [$($lhs2)+], [$($rhs2)+]} {Int, Sub, sub, -=, [$($lhs2)+], [$($rhs2)+]} {Int, Mul, mul, *=, [$($lhs2)+], [$($rhs2)+]} ); )* }; } impl_ops_times!([Fps<T, F>] * [&Self], [Fps<T, F>] * [Self], [&Fps<T, F>] * [Self]; [Fps<T, F>] * [T], [&Fps<T, F>] * [T]); macro_rules! impl_assign_ops { ($([$($rhs:tt)+]),*) => { $( impl<T: Int, F: Conv<T>> AddAssign<$($rhs)+> for Fps<T, F> { fn add_assign(&mut self, rhs: $($rhs)+) { if rhs.lens() > self.lens() {self.resize(rhs.lens())}; self.data.iter_mut().zip(rhs.data.iter()).for_each(|(e, r)| *e += *r); } } impl<T: Int, F: Conv<T>> SubAssign<$($rhs)+> for Fps<T, F> { fn sub_assign(&mut self, rhs: $($rhs)+) { if rhs.lens() > self.lens() {self.resize(rhs.lens())}; self.data.iter_mut().zip(rhs.data.iter()).for_each(|(e,r)| *e -= *r); self.shrink(); } } impl<T: Int, F: Conv<T>> MulAssign<$($rhs)+> for Fps<T, F> { fn mul_assign(&mut self, rhs: $($rhs)+) { self.data = F::convolution(&self.data, &rhs.data); } } impl<T: ModInt, F: Conv<T>> RemAssign<$($rhs)+> for Fps<T, F> { fn rem_assign(&mut self, rhs: $($rhs)+) { *self -= &(&*self / &rhs * rhs); } } impl<T: ModInt, F: Conv<T>> DivAssign<$($rhs)+> for Fps<T, F> { fn div_assign(&mut self, rhs: $($rhs)+) { let n = self.lens(); self.data = F::convolution(&self.data, &rhs.inv(n).data); self.resize(n); } } )* }; } impl_assign_ops!([Self], [&Self]); impl<T: Int, F: Conv<T>> Neg for &Fps<T, F> { type Output = Fps<T, F>; fn neg(self) -> Self::Output { let data = self.data.map(|x| T::zero() - x); Fps { data, phantom: PhantomData, } } } impl<T: Int, F: Conv<T>> AddAssign<T> for Fps<T, F> { fn add_assign(&mut self, rhs: T) { if self.is_empty() { self.resize(1) }; self[0] += rhs; } } impl<T: Int, F: Conv<T>> SubAssign<T> for Fps<T, F> { fn sub_assign(&mut self, rhs: T) { if self.is_empty() { self.resize(1); } self[0] -= rhs; self.shrink(); } } impl<T: Int, F: Conv<T>> MulAssign<T> for Fps<T, F> { fn mul_assign(&mut self, rhs: T) { for e in self.data.iter_mut() { *e *= rhs; } } } impl<T: Int, F: Conv<T>> Shr<isize> for &Fps<T, F> { type Output = Fps<T, F>; fn shr(self, rhs: isize) -> Self::Output { if self.lens() <= rhs { return Fps::<T, F>::empty(); } Self::Output::from(&self.data[rhs..]) } } impl<T: Int, F: Conv<T>> Shl<isize> for &Fps<T, F> { type Output = Fps<T, F>; fn shl(self, rhs: isize) -> Self::Output { let mut data = list![T::zero();rhs]; data.append(&self.data); Self::Output::new(data) } } impl<T: Int, F: Conv<T>> Index<isize> for Fps<T, F> { type Output = T; fn index(&self, index: isize) -> &T { &self.data[index] } } impl<T: Int, F: Conv<T>> IndexMut<isize> for Fps<T, F> { fn index_mut(&mut self, index: isize) -> &mut T { &mut self.data[index] } } #[macro_export] macro_rules! fps { ([$($args:tt)+] [$($tpe:tt)+]) => {$crate::fps::formal_power_series::Fps::<_, $($tpe)+>::new($crate::list![$($args)+])}; } } } pub mod independent { pub mod integer { use std::fmt::Display; use std::ops::*; pub trait Int: Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self> + AddAssign + SubAssign + MulAssign + DivAssign + RemAssign + std::hash::Hash + PartialEq + Eq + PartialOrd + Ord + Copy + Display { fn to_u8(&self) -> u8; fn to_u16(&self) -> u16; fn to_u32(&self) -> u32; fn to_u64(&self) -> u64; fn to_u128(&self) -> u128; fn to_i8(&self) -> i8; fn to_i16(&self) -> i16; fn to_i32(&self) -> i32; fn to_i64(&self) -> i64; fn to_i128(&self) -> i128; fn to_usize(&self) -> usize; fn to_isize(&self) -> isize; fn from_u8(x: u8) -> Self; fn from_u16(x: u16) -> Self; fn from_u32(x: u32) -> Self; fn from_u64(x: u64) -> Self; fn from_u128(x: u128) -> Self; fn from_i8(x: i8) -> Self; fn from_i16(x: i16) -> Self; fn from_i32(x: i32) -> Self; fn from_i64(x: i64) -> Self; fn from_i128(x: i128) -> Self; fn from_usize(x: usize) -> Self; fn from_isize(x: isize) -> Self; fn zero() -> Self; fn one() -> Self; fn next(&self) -> Self { *self + Self::one() } fn powint(&self, n: i64) -> Self; } #[macro_export] macro_rules! impl_integer_functions { ($to_op:expr, $from_op:expr, $pow:expr) => { impl_integer_functions!( $to_op, $from_op, $pow, to_u8, from_u8, u8, to_u16, from_u16, u16, to_u32, from_u32, u32, to_u64, from_u64, u64, to_u128, from_u128, u128, to_i8, from_i8, i8, to_i16, from_i16, i16, to_i32, from_i32, i32, to_i64, from_i64, i64, to_i128, from_i128, i128, to_usize, from_usize, usize, to_isize, from_isize, isize ); }; ($to_op:expr, $from_op:expr, $pow:expr, $($tofn:ident, $fromfn:ident, $tpe:ident),*) => { $( fn $tofn(&self) -> $tpe { $to_op(self) as $tpe } fn $fromfn(x: $tpe) -> Self { $from_op(x) } )* fn zero() -> Self {$from_op(0)} fn one() -> Self {$from_op(1)} fn powint(&self, n: i64) -> Self {$pow(self, n)} }; } macro_rules! impl_integer { ($($tpe:ident),*) => { $( impl Int for $tpe { impl_integer_functions!( |s: &Self| *s, |x| x as $tpe, |s: &Self, n: i64| s.pow(n as u32) ); } )* }; } impl_integer!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize); } } pub mod arraylist { use std::ops::*; use std::slice::Iter; use std::fmt::Formatter; use std::iter::FromIterator; use crate::independent::integer::Int; #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct List<T> { pub data: Vec<T>, } impl<T> List<T> { #[inline] pub fn new() -> List<T> { List { data: vec![] } } #[inline] pub fn init(init: T, n: isize) -> List<T> where T: Clone, { List { data: vec![init; n as usize], } } #[inline] pub fn pop(&mut self) -> Option<T> { self.data.pop() } #[inline] pub fn push(&mut self, item: T) { self.data.push(item); } #[inline] pub fn append(&mut self, other: &lst<T>) where T: Clone, { self.data.append(&mut other.to_vec()); } #[inline] pub fn resize(&mut self, new_len: isize, value: T) where T: Clone, { self.data.resize(new_len as usize, value); } } macro_rules! impl_idx { ($($tpe:ty, $t:ident [$($output:tt)+], $slf:ident, $index:ident, $f:expr),*) => { $(impl<$t> Index<$tpe> for List<$t> { type Output = $($output)+; #[inline] fn index(&$slf, $index: $tpe) -> &Self::Output {$f} })* $(impl<$t> Index<$tpe> for lst<$t> { type Output = $($output)+; #[inline] fn index(&$slf, $index: $tpe) -> &Self::Output {$f} })* } } macro_rules! impl_idx_mut { ($($tpe:ty, $slf:ident, $index:ident, $f:expr),*) => { $(impl<T> IndexMut<$tpe> for List<T> { #[inline] fn index_mut(&mut $slf, $index: $tpe) -> &mut Self::Output {$f} })* $(impl<T> IndexMut<$tpe> for lst<T> { #[inline] fn index_mut(&mut $slf, $index: $tpe) -> &mut Self::Output {$f} })* }; } macro_rules! impl_idx_slice { ($($tpe:ty),*) => { impl_idx!($($tpe, T [lst<T>], self, i, self.as_slice(i)),*); impl_idx_mut!($($tpe, self, i, self.as_slice_mut(i)),*); }; } impl_idx! { isize, T [T], self, i, self.at(i), char, T [T], self, i, self.at(i as isize - 'a' as isize) } impl_idx_slice! { Range<isize>, RangeTo<isize>, RangeFrom<isize>, RangeFull, RangeInclusive<isize>, RangeToInclusive<isize> } impl_idx_mut! { isize, self, i, self.at_mut(i), char, self, i, self.at_mut(i as isize - 'a' as isize) } impl<T> FromIterator<T> for List<T> { #[inline] fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self { List { data: iter.into_iter().collect(), } } } impl<T> IntoIterator for List<T> { type Item = T; type IntoIter = std::vec::IntoIter<T>; #[inline] fn into_iter(self) -> std::vec::IntoIter<T> { self.data.into_iter() } } macro_rules! impl_traits { ($($tpe:tt),*) => { $( impl<T: std::fmt::Display> std::fmt::Display for $tpe<T> { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.iter().map(|x| format!("{}", x)).collect::<Vec<_>>().join(" ")) } } impl<T: std::fmt::Debug> std::fmt::Debug for $tpe<T> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.data.fmt(f) } } impl<'a, T> IntoIterator for &'a $tpe<T> { type Item = &'a T; type IntoIter = Iter<'a, T>; #[inline] fn into_iter(self) -> Iter<'a, T> { self.iter() } } )* }; } impl_traits!(List, lst); impl<T> From<Vec<T>> for List<T> { #[inline] fn from(vec: Vec<T>) -> Self { List { data: vec } } } impl<T: Clone> From<&[T]> for List<T> { #[inline] fn from(slice: &[T]) -> Self { slice.iter().cloned().collect() } } impl<T> Deref for List<T> { type Target = lst<T>; #[inline] fn deref(&self) -> &lst<T> { lst::new(&self.data) } } impl<T> DerefMut for List<T> { #[inline] fn deref_mut(&mut self) -> &mut lst<T> { lst::new_mut(&mut self.data) } } #[macro_export] macro_rules! list { () => { $crate::arraylist::List::new() }; ($($v:expr),+ $(,)?) => { $crate::arraylist::List::from([$($v),+].to_vec()) }; ($v:expr; $a:expr) => { $crate::arraylist::List::init($v, $a)}; ($v:expr; $a:expr; $($rest:expr);+) => { $crate::arraylist::List::init(list!($v; $($rest);+), $a) }; } #[allow(non_camel_case_types)] #[derive(PartialEq, Eq, PartialOrd, Ord)] #[repr(transparent)] pub struct lst<T> { data: [T], } impl<T> lst<T> { #[inline] pub fn new(slice: &[T]) -> &Self { unsafe { &*(slice as *const [T] as *const Self) } } #[inline] pub fn new_mut(slice: &mut [T]) -> &mut Self { unsafe { &mut *(slice as *mut [T] as *mut Self) } } #[inline] pub fn lens(&self) -> isize { self.data.len() as isize } #[inline] pub fn list(&self) -> List<T> where T: Clone, { self.cloned().collect() } #[inline] fn at(&self, index: isize) -> &T { if cfg!(debug_assertions) { self.data.index(index as usize) } else { unsafe { self.data.get_unchecked(index as usize) } } } #[inline] fn at_mut(&mut self, index: isize) -> &mut T { if cfg!(debug_assertions) { self.data.index_mut(index as usize) } else { unsafe { self.data.get_unchecked_mut(index as usize) } } } #[inline] pub fn as_slice(&self, range: impl RangeBounds<isize>) -> &lst<T> { if cfg!(debug_assertions) { lst::new(self.data.index(self.rgm(range))) } else { unsafe { lst::new(self.data.get_unchecked(self.rgm(range))) } } } #[inline] pub fn as_slice_mut(&mut self, range: impl RangeBounds<isize>) -> &mut lst<T> { if cfg!(debug_assertions) { lst::new_mut(self.data.index_mut(self.rgm(range))) } else { let r = self.rgm(range); unsafe { lst::new_mut(self.data.get_unchecked_mut(r)) } } } #[inline] pub fn cloned(&self) -> std::iter::Cloned<Iter<T>> where T: Clone, { self.iter().cloned() } #[inline] pub fn map<B, F>(&self, f: F) -> List<B> where T: Clone, F: FnMut(T) -> B, { self.cloned().map(f).collect() } #[inline] pub fn take_while<P>(&self, predicate: P) -> List<T> where T: Clone, P: FnMut(&T) -> bool, { self.cloned().take_while(predicate).collect() } #[inline] pub fn sum(&self) -> T where T: Int, { self.cloned().fold(T::zero(), |acc, x| acc + x) } #[inline] pub fn max_item(&self) -> Option<&T> where T: Ord, { self.iter().max() } #[inline] pub fn fill(&mut self, r: impl RangeBounds<isize>, item: T) where T: Clone, { for i in self.rgm(r) { self.data[i] = item.clone(); } } #[inline] fn rgm(&self, r: impl RangeBounds<isize>) -> Range<usize> { (match r.start_bound() { Bound::Included(x) => *x as usize, Bound::Excluded(x) => *x as usize + 1, _ => 0, }) .max(0)..(match r.end_bound() { Bound::Included(x) => *x as usize + 1, Bound::Excluded(x) => *x as usize, _ => self.len(), }) .min(self.len()) } } impl lst<isize> { #[inline] pub fn hist(&self, exclusive_ub: isize) -> List<isize> { let mut cnt = List::init(0, exclusive_ub); for &i in self { cnt[i] += 1; } cnt } } impl<T> Deref for lst<T> { type Target = [T]; #[inline] fn deref(&self) -> &[T] { &self.data } } impl<T> DerefMut for lst<T> { #[inline] fn deref_mut(&mut self) -> &mut [T] { &mut self.data } } impl<'a, T> From<&'a [T]> for &'a lst<T> { #[inline] fn from(slice: &'a [T]) -> Self { lst::new(slice) } } }