結果
問題 | No.1973 Divisor Sequence |
ユーザー |
![]() |
提出日時 | 2022-06-18 09:45:33 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 12 ms / 2,000 ms |
コード長 | 8,181 bytes |
コンパイル時間 | 13,795 ms |
コンパイル使用メモリ | 378,460 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-10-09 20:44:43 |
合計ジャッジ時間 | 13,831 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 22 |
コンパイルメッセージ
warning: type `mat` should have an upper camel case name --> src/main.rs:100:6 | 100 | type mat = Vec<Vec<Modulo>>; | ^^^ help: convert the identifier to upper camel case: `Mat` | = note: `#[warn(non_camel_case_types)]` on by default warning: associated items `set_modulus`, `pow`, and `inv` are never used --> src/main.rs:139:8 | 138 | impl Modulo { | ----------- associated items in this implementation 139 | fn set_modulus(m: i64) { | ^^^^^^^^^^^ ... 157 | fn pow(self, p: i64) -> Modulo { | ^^^ ... 169 | fn inv(self) -> Modulo { | ^^^ | = note: `#[warn(dead_code)]` on by default
ソースコード
#![allow(unused_imports)]use std::cmp::*;use std::collections::*;use std::io::Write;use std::ops::Bound::*;#[allow(unused_macros)]macro_rules! debug {($($e:expr),*) => {#[cfg(debug_assertions)]$({let (e, mut err) = (stringify!($e), std::io::stderr());writeln!(err, "{} = {:?}", e, $e).unwrap()})*};}fn main() {let v = read_vec::<i64>();let (n, m) = (v[0], v[1]);let mut ans = Modulo(1);let mut root_n = 0;for i in 1.. {if i * i > m {root_n = i;break;}}let primes = get_primes(root_n);let mut mm = m;let mut p_dividors = vec![];for &p in &primes {if mm % p == 0 {p_dividors.push(p);}while mm % p == 0 {mm /= p;}}if mm != 1 {p_dividors.push(mm);}for p in p_dividors {let mut dividors = vec![];let mut coef = 1;while m % coef == 0 {dividors.push(coef);coef *= p;}let mut cross = vec![vec![Modulo(0); dividors.len()]; dividors.len()];for (i, &d1) in dividors.iter().enumerate() {for (j, &d2) in dividors.iter().enumerate() {if m as i128 % (d1 as i128 * d2 as i128) == 0 {cross[i][j] = Modulo(1);}}}let a = matpow(&cross, n as u64);ans *= a[0].iter().sum::<Modulo>();}println!("{}", ans);}fn get_primes(n: i64) -> Vec<i64> {let mut is_prime = vec![true; n as usize + 1];let mut primes = Vec::new();is_prime[0] = false;is_prime[1] = false;for i in 2..n + 1 {if is_prime[i as usize] {primes.push(i);let mut j = 2 * i;while j <= n {is_prime[j as usize] = false;j += i;}}}primes}fn read<T: std::str::FromStr>() -> T {let mut s = String::new();std::io::stdin().read_line(&mut s).ok();s.trim().parse().ok().unwrap()}fn read_vec<T: std::str::FromStr>() -> Vec<T> {read::<String>().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()}type mat = Vec<Vec<Modulo>>;fn mat_zeros(n: usize, m: usize) -> mat {vec![vec![Modulo(0); m]; n]}fn matmul(a: &mat, b: &mat) -> mat {let mut c = mat_zeros(a.len(), b[0].len());for i in 0..a.len() {for k in 0..b.len() {for j in 0..b[0].len() {c[i][j] += a[i][k] * b[k][j];}}}c}fn matpow(a: &mat, n: u64) -> mat {let mut b = mat_zeros(a.len(), a.len());for i in 0..a.len() {b[i][i] = Modulo(1);}let mut n = n;let mut a: mat = a.clone();while n > 0 {if n & 1 == 1 {b = matmul(&a, &b);}a = matmul(&a, &a);n >>= 1;}b}#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]struct Modulo(i64);static mut MODULUS: i64 = 1000_000_000 + 7;impl Modulo {fn set_modulus(m: i64) {unsafe {MODULUS = m;}}fn get_modulus() -> i64 {unsafe { MODULUS }}fn new(x: i64) -> Modulo {let m = Modulo::get_modulus();if x < 0 {Modulo(x % m + m)} else if x < m {Modulo(x)} else {Modulo(x % m)}}fn pow(self, p: i64) -> Modulo {if p == 0 {Modulo(1)} else {let mut t = self.pow(p / 2);t *= t;if p & 1 == 1 {t *= self;}t}}fn inv(self) -> Modulo {self.pow(Modulo::get_modulus() - 2)}}impl std::fmt::Display for Modulo {fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {self.0.fmt(f)}}impl std::ops::AddAssign for Modulo {fn add_assign(&mut self, other: Modulo) {let m = Modulo::get_modulus();self.0 += other.0;if self.0 >= m {self.0 -= m;}}}impl std::ops::MulAssign for Modulo {fn mul_assign(&mut self, other: Modulo) {let m = Modulo::get_modulus();self.0 *= other.0;self.0 %= m;}}impl std::ops::SubAssign for Modulo {fn sub_assign(&mut self, other: Modulo) {let m = Modulo::get_modulus();self.0 += m - other.0;if self.0 >= m {self.0 -= m;}}}macro_rules! impl_modulo_ops {($imp:ident, $method:ident, $assign_imp:ident, $assign_method:ident) => {impl<'a> std::ops::$assign_imp<&'a Modulo> for Modulo {fn $assign_method(&mut self, other: &'a Modulo) {std::ops::$assign_imp::$assign_method(self, *other);}}impl std::ops::$imp for Modulo {type Output = Modulo;fn $method(self, other: Modulo) -> Modulo {let mut x = self;std::ops::$assign_imp::$assign_method(&mut x, other);x}}impl<'a> std::ops::$imp<Modulo> for &'a Modulo {type Output = Modulo;fn $method(self, other: Modulo) -> Modulo {std::ops::$imp::$method(*self, other)}}impl<'a> std::ops::$imp<&'a Modulo> for Modulo {type Output = Modulo;fn $method(self, other: &'a Modulo) -> Modulo {std::ops::$imp::$method(self, *other)}}impl<'a, 'b> std::ops::$imp<&'b Modulo> for &'a Modulo {type Output = Modulo;fn $method(self, other: &'b Modulo) -> Modulo {std::ops::$imp::$method(*self, *other)}}impl std::ops::$assign_imp<i64> for Modulo {fn $assign_method(&mut self, other: i64) {std::ops::$assign_imp::$assign_method(self, Modulo::new(other));}}impl<'a> std::ops::$assign_imp<&'a i64> for Modulo {fn $assign_method(&mut self, other: &'a i64) {std::ops::$assign_imp::$assign_method(self, *other);}}impl std::ops::$imp<i64> for Modulo {type Output = Modulo;fn $method(self, other: i64) -> Modulo {let mut x = self;std::ops::$assign_imp::$assign_method(&mut x, other);x}}impl<'a> std::ops::$imp<&'a i64> for Modulo {type Output = Modulo;fn $method(self, other: &'a i64) -> Modulo {std::ops::$imp::$method(self, *other)}}impl<'a> std::ops::$imp<i64> for &'a Modulo {type Output = Modulo;fn $method(self, other: i64) -> Modulo {std::ops::$imp::$method(*self, other)}}impl<'a, 'b> std::ops::$imp<&'b i64> for &'a Modulo {type Output = Modulo;fn $method(self, other: &'b i64) -> Modulo {std::ops::$imp::$method(*self, *other)}}};}impl_modulo_ops!(Add, add, AddAssign, add_assign);impl_modulo_ops!(Mul, mul, MulAssign, mul_assign);impl_modulo_ops!(Sub, sub, SubAssign, sub_assign);use std::iter::Sum;impl Sum for Modulo {fn sum<I>(iter: I) -> SelfwhereI: Iterator<Item = Modulo>,{iter.fold(Modulo(0), |a, b| a + b)}}impl<'a> Sum<&'a Modulo> for Modulo {fn sum<I>(iter: I) -> SelfwhereI: Iterator<Item = &'a Self>,{iter.fold(Modulo(0), |a, b| a + b)}}use std::iter::Product;impl Product for Modulo {fn product<I>(iter: I) -> SelfwhereI: Iterator<Item = Modulo>,{iter.fold(Modulo(1), |a, b| a * b)}}impl<'a> Product<&'a Modulo> for Modulo {fn product<I>(iter: I) -> SelfwhereI: Iterator<Item = &'a Self>,{iter.fold(Modulo(1), |a, b| a * b)}}