結果

問題 No.502 階乗を計算するだけ
ユーザー guriceringuricerin
提出日時 2019-07-07 10:02:48
言語 Rust
(1.77.0)
結果
RE  
実行時間 -
コード長 9,166 bytes
コンパイル時間 1,170 ms
コンパイル使用メモリ 181,440 KB
実行使用メモリ 812,212 KB
最終ジャッジ日時 2024-04-14 22:46:40
合計ジャッジ時間 4,396 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 1 ms
6,940 KB
testcase_02 AC 1 ms
6,944 KB
testcase_03 AC 1 ms
6,940 KB
testcase_04 AC 1 ms
6,944 KB
testcase_05 AC 1 ms
6,944 KB
testcase_06 AC 1 ms
6,944 KB
testcase_07 AC 1 ms
6,940 KB
testcase_08 AC 1 ms
6,940 KB
testcase_09 AC 1 ms
6,940 KB
testcase_10 AC 1 ms
6,944 KB
testcase_11 AC 1 ms
6,940 KB
testcase_12 AC 1 ms
6,940 KB
testcase_13 AC 1 ms
6,944 KB
testcase_14 AC 1 ms
6,940 KB
testcase_15 AC 1 ms
6,940 KB
testcase_16 AC 1 ms
6,940 KB
testcase_17 AC 1 ms
6,940 KB
testcase_18 AC 1 ms
6,940 KB
testcase_19 AC 1 ms
6,940 KB
testcase_20 AC 0 ms
6,940 KB
testcase_21 AC 1 ms
6,944 KB
testcase_22 AC 19 ms
16,600 KB
testcase_23 AC 7 ms
6,940 KB
testcase_24 AC 13 ms
11,664 KB
testcase_25 AC 3 ms
6,940 KB
testcase_26 AC 9 ms
7,168 KB
testcase_27 AC 6 ms
6,944 KB
testcase_28 AC 8 ms
6,940 KB
testcase_29 AC 4 ms
6,940 KB
testcase_30 AC 18 ms
15,392 KB
testcase_31 AC 10 ms
8,412 KB
testcase_32 RE -
testcase_33 RE -
testcase_34 MLE -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
testcase_40 -- -
testcase_41 -- -
testcase_42 -- -
testcase_43 -- -
testcase_44 -- -
testcase_45 -- -
testcase_46 -- -
testcase_47 -- -
testcase_48 -- -
testcase_49 -- -
testcase_50 -- -
testcase_51 -- -
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: field `invfact` is never read
   --> main.rs:264:9
    |
262 |     pub struct BiCoef {
    |                ------ field in this struct
263 |         fact: Vec<ModInt>,
264 |         invfact: Vec<ModInt>,
    |         ^^^^^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: methods `invfact`, `perm`, `comb`, and `multi_comb` are never used
   --> main.rs:298:16
    |
267 |     impl BiCoef {
    |     ----------- methods in this implementation
...
298 |         pub fn invfact(&self, n: usize) -> ModInt {
    |                ^^^^^^^
...
308 |         pub fn perm(&self, n: i64, r: i64) -> ModInt {
    |                ^^^^
...
318 |         pub fn comb(&self, n: i64, r: i64) -> ModInt {
    |                ^^^^
...
328 |         pub fn multi_comb(&self, n: i64, r: i64) -> ModInt {
    |                ^^^^^^^^^^

warning: 2 warnings emitted

ソースコード

diff #

// Original: https://github.com/tanakh/competitive-rs
#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };

    ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, [ $t:tt ]) => {
        {
            let len = read_value!($next, usize);
            (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
        }
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, bytes) => {
        read_value!($next, String).into_bytes()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(dead_code)]
fn chmin<T>(x: &mut T, y: T) -> bool
where
    T: PartialOrd + Copy,
{
    *x > y && {
        *x = y;
        true
    }
}

#[allow(dead_code)]
fn chmax<T>(x: &mut T, y: T) -> bool
where
    T: PartialOrd + Copy,
{
    *x < y && {
        *x = y;
        true
    }
}

mod mod_int {
    use std::ops::*;

    pub trait Mod: Copy {
        fn m() -> i64;
    }

    #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
    pub struct ModInt<M> {
        pub val: i64,
        phantom: std::marker::PhantomData<M>,
    }

    impl<M: Mod> ModInt<M> {
        // x >= 0
        pub fn new(val: i64) -> Self {
            ModInt::new_internal(val % M::m())
        }

        fn new_internal(val: i64) -> Self {
            ModInt {
                val: val,
                phantom: std::marker::PhantomData,
            }
        }

        pub fn pow(self, mut e: i64) -> Self {
            debug_assert!(e >= 0);
            let mut sum = ModInt::new_internal(1);
            let mut cur = self;
            while e > 0 {
                if e % 2 != 0 {
                    sum *= cur;
                }
                cur *= cur;
                e /= 2;
            }
            sum
        }

        // mod m における self.val の逆元
        #[allow(dead_code)]
        pub fn inv(self) -> Self {
            self.pow(M::m() - 2)
        }
    }

    impl<M: Mod, T: Into<ModInt<M>>> Add<T> for ModInt<M> {
        type Output = Self;
        fn add(self, other: T) -> Self {
            let other = other.into();
            let mut sum = self.val + other.val;
            if sum >= M::m() {
                sum -= M::m();
            }
            ModInt::new_internal(sum)
        }
    }

    impl<M: Mod, T: Into<ModInt<M>>> Sub<T> for ModInt<M> {
        type Output = Self;
        fn sub(self, other: T) -> Self {
            let other = other.into();
            let mut sum = self.val - other.val;
            if sum < 0 {
                sum += M::m();
            }
            ModInt::new_internal(sum)
        }
    }

    impl<M: Mod, T: Into<ModInt<M>>> Mul<T> for ModInt<M> {
        type Output = Self;
        fn mul(self, other: T) -> Self {
            ModInt::new_internal(self.val * other.into().val % M::m())
        }
    }

    impl<M: Mod, T: Into<ModInt<M>>> AddAssign<T> for ModInt<M> {
        fn add_assign(&mut self, other: T) {
            *self = *self + other;
        }
    }

    impl<M: Mod, T: Into<ModInt<M>>> SubAssign<T> for ModInt<M> {
        fn sub_assign(&mut self, other: T) {
            *self = *self - other;
        }
    }

    impl<M: Mod, T: Into<ModInt<M>>> MulAssign<T> for ModInt<M> {
        fn mul_assign(&mut self, other: T) {
            *self = *self * other;
        }
    }

    impl<M: Mod> Neg for ModInt<M> {
        type Output = Self;
        fn neg(self) -> Self {
            ModInt::new(0) - self
        }
    }

    impl<M: Mod> std::fmt::Display for ModInt<M> {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            self.val.fmt(f)
        }
    }

    impl<M: Mod> std::fmt::Debug for ModInt<M> {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            let (mut a, mut b, _) = red(self.val, M::m());
            if b < 0 {
                a = -a;
                b = -b;
            }
            write!(f, "{}/{}", a, b)
        }
    }

    impl<M: Mod> From<i64> for ModInt<M> {
        fn from(val: i64) -> Self {
            Self::new(val)
        }
    }

    // Finds the simplest fraction x/y congruent to r mod p.
    // The return value (x, y, z) satisfies x = y * r + z * p.
    fn red(r: i64, p: i64) -> (i64, i64, i64) {
        if r.abs() <= 10000 {
            return (r, 1, 0);
        }
        let mut nxt_r = p % r;
        let mut q = p / r;
        if 2 * nxt_r >= r {
            nxt_r -= r;
            q += 1;
        }
        if 2 * nxt_r <= -r {
            nxt_r += r;
            q -= 1;
        }
        let (x, z, y) = red(nxt_r, r);
        (x, y - q * z, z)
    }
} // mod mod_int

macro_rules! define_mod {
    ($struct_name: ident, $modulo: expr) => {
        #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
        struct $struct_name {}
        impl mod_int::Mod for $struct_name {
            fn m() -> i64 {
                $modulo
            }
        }
    };
}

const MOD: i64 = 1e9 as i64 + 7;
define_mod!(P, MOD);
type ModInt = mod_int::ModInt<P>;

mod mod_comb {
    use super::ModInt;

    pub struct BiCoef {
        fact: Vec<ModInt>,
        invfact: Vec<ModInt>,
    }

    impl BiCoef {
        pub fn new(n: usize) -> Self {
            let mut fact: Vec<ModInt> = vec![1.into(); n + 1];
            let mut invfact: Vec<ModInt> = vec![1.into(); n + 1];
            for i in 0..n {
                fact[i + 1] = fact[i] * ModInt::new(i as i64 + 1);
            }
            invfact[n] = fact[n].inv();
            for i in (0..n).rev() {
                invfact[i] = invfact[i + 1] * ModInt::new(i as i64 + 1);
            }
            BiCoef {
                fact: fact,
                invfact: invfact,
            }
        }

        pub fn fact(&self, n: usize) -> ModInt {
            if let Some(x) = self.fact.get(n) {
                *x
            } else if n >= super::MOD as usize {
                ModInt::new(0)
            } else {
                let mut res = 1.into();
                for i in 1..(n + 1) {
                    res *= ModInt::new(i as i64 + 1);
                }
                res
            }
        }

        pub fn invfact(&self, n: usize) -> ModInt {
            if let Some(x) = self.invfact.get(n as usize) {
                *x
            } else {
                self.fact(n).inv()
            }
        }
        #[doc = " `nPr = n! / (n - r)!`"]
        #[doc = ""]
        #[doc = " `O(1)` if n and r are smaller than input in `new` method."]
        pub fn perm(&self, n: i64, r: i64) -> ModInt {
            if n >= r {
                self.fact(n as usize) * self.invfact((n - r) as usize)
            } else {
                0.into()
            }
        }
        #[doc = " `nCr = n! / (n - r)! / r!`."]
        #[doc = ""]
        #[doc = " `O(1)` if n and r are smaller than input in `new` method."]
        pub fn comb(&self, n: i64, r: i64) -> ModInt {
            if n >= r {
                self.fact(n as usize) * self.invfact((n - r) as usize) * self.invfact(r as usize)
            } else {
                ModInt::from(0)
            }
        }
        #[doc = " `(n + k - 1)! / k!`."]
        #[doc = ""]
        #[doc = " `O(1)` if n and r are smaller than input in `new` method."]
        pub fn multi_comb(&self, n: i64, r: i64) -> ModInt {
            if r == 0 {
                ModInt::from(1)
            } else {
                self.comb(n + r - 1, r)
            }
        }
    }
}

#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque};

fn main() {
    input!(n: usize);
    use mod_comb::*;
    let bi = BiCoef::new(n);
    if n >= MOD as usize {
        println!("0");
    } else {
        println!("{}", bi.fact(n));
    }
}
0