結果
| 問題 |
No.2211 Frequency Table of GCD
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-02-10 22:08:26 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 928 ms / 2,000 ms |
| コード長 | 5,026 bytes |
| コンパイル時間 | 12,139 ms |
| コンパイル使用メモリ | 381,680 KB |
| 実行使用メモリ | 9,504 KB |
| 最終ジャッジ日時 | 2024-07-07 18:02:29 |
| 合計ジャッジ時間 | 25,661 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 26 |
ソースコード
#[macro_export]
macro_rules! read_line {
($($xs: tt)*) => {
let mut buf = String::new();
std::io::stdin().read_line(&mut buf).unwrap();
let mut iter = buf.split_whitespace();
expand!(iter, $($xs)*);
};
}
#[macro_export]
macro_rules! expand {
($iter: expr,) => {};
($iter: expr, mut $var: ident : $type: tt, $($xs: tt)*) => {
let mut $var = value!($iter, $type);
expand!($iter, $($xs)*);
};
($iter: expr, $var: ident : $type: tt, $($xs: tt)*) => {
let $var = value!($iter, $type);
expand!($iter, $($xs)*);
};
}
#[macro_export]
macro_rules! value {
($iter:expr, ($($type: tt),*)) => {
($(value!($iter, $type)),*)
};
($iter: expr, [$type: tt; $len: expr]) => {
(0..$len).map(|_| value!($iter, $type)).collect::<Vec<_>>()
};
($iter: expr, Chars) => {
value!($iter, String).unwrap().chars().collect::<Vec<_>>()
};
($iter: expr, $type: ty) => {
if let Some(v) = $iter.next() {
v.parse::<$type>().ok()
} else {
None
}
};
}
use std::{fmt, ops};
const MOD: usize = 998244353; // 119 * (1 << 23) + 1
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ModInt {
value: usize,
}
impl ModInt {
pub fn new(value: usize) -> ModInt {
ModInt { value: value % MOD }
}
pub fn value(&self) -> usize {
self.value
}
pub fn inverse(&self) -> ModInt {
// (a, b) -> (x, y) s.t. a * x + b * y = gcd(a, b)
fn extended_gcd(a: isize, b: isize) -> (isize, isize) {
if (a, b) == (1, 0) {
(1, 0)
} else {
let (x, y) = extended_gcd(b, a % b);
(y, x - (a / b) * y)
}
}
let (x, _y) = extended_gcd(self.value() as isize, MOD as isize);
ModInt::new((MOD as isize + x) as usize)
}
// a^n
pub fn pow(&self, mut n: usize) -> ModInt {
let mut res = ModInt::new(1);
let mut x = *self;
while n > 0 {
if n % 2 == 1 {
res *= x;
}
x *= x;
n /= 2;
}
res
}
}
impl ops::Add for ModInt {
type Output = ModInt;
fn add(self, other: Self) -> Self {
ModInt::new(self.value + other.value)
}
}
impl ops::Sub for ModInt {
type Output = ModInt;
fn sub(self, other: Self) -> Self {
ModInt::new(MOD + self.value - other.value)
}
}
impl ops::Mul for ModInt {
type Output = ModInt;
fn mul(self, other: Self) -> Self {
ModInt::new(self.value * other.value)
}
}
impl ops::Div for ModInt {
type Output = ModInt;
fn div(self, other: Self) -> Self {
self * other.inverse()
}
}
impl ops::AddAssign for ModInt {
fn add_assign(&mut self, other: Self) {
*self = *self + other;
}
}
impl ops::SubAssign for ModInt {
fn sub_assign(&mut self, other: Self) {
*self = *self - other;
}
}
impl ops::MulAssign for ModInt {
fn mul_assign(&mut self, other: Self) {
*self = *self * other;
}
}
impl ops::DivAssign for ModInt {
fn div_assign(&mut self, other: Self) {
*self = *self / other;
}
}
// n!
pub fn factorial(n: usize) -> ModInt {
(1..=n).fold(ModInt::new(1), |x, y| x * ModInt::new(y))
}
// nPr
pub fn permutation(n: usize, r: usize) -> ModInt {
if n < r {
ModInt::new(0)
} else {
(n - r + 1..=n).fold(ModInt::new(1), |x, y| x * ModInt::new(y))
}
}
// nCr
pub fn combination(n: usize, r: usize) -> ModInt {
if n < r {
ModInt::new(0)
} else {
permutation(n, r) / factorial(r)
}
}
// nHr
pub fn homogeneous(n: usize, r: usize) -> ModInt {
combination(n + r - 1, r)
}
// Catalan number
pub fn catalan(n: usize) -> ModInt {
combination(2 * n, n) / ModInt::new(n + 1)
}
impl fmt::Display for ModInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value())
}
}
pub fn gen_divisors(n: usize) -> Vec<usize> {
let mut res = vec![];
for i in (1..).take_while(|&x| x * x <= n) {
if n % i == 0 {
res.push(i);
if i * i < n {
res.push(n / i);
}
}
}
res.sort();
res
}
fn main() {
read_line!(n: usize, m: usize,);
let n = n.unwrap();
let m = m.unwrap();
read_line!(a: [usize; n],);
let a = a.into_iter().map(|x| x.unwrap()).collect::<Vec<_>>();
let mut cnt = vec![0; m + 1];
for i in 0..n {
for d in gen_divisors(a[i]) {
cnt[d] += 1;
}
}
let mut ans = vec![ModInt::new(0); m + 1];
for i in 1..=m {
ans[i] = ModInt::new(2).pow(cnt[i]) - ModInt::new(1);
}
for i in (1..=m).rev() {
for d in gen_divisors(i) {
if d < i {
ans[d] = ans[d] - ans[i];
}
}
}
for i in 1..=m {
println!("{}", ans[i]);
}
}