結果

問題 No.1011 Infinite Stairs
ユーザー tzyvrntzyvrn
提出日時 2020-03-20 23:04:46
言語 Rust
(1.77.0 + proconio)
結果
TLE  
実行時間 -
コード長 7,939 bytes
コンパイル時間 12,489 ms
コンパイル使用メモリ 401,996 KB
実行使用メモリ 442,752 KB
最終ジャッジ日時 2024-12-15 08:14:36
合計ジャッジ時間 48,006 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
13,640 KB
testcase_01 AC 1 ms
286,752 KB
testcase_02 AC 25 ms
21,152 KB
testcase_03 TLE -
testcase_04 TLE -
testcase_05 TLE -
testcase_06 AC 1 ms
13,640 KB
testcase_07 AC 142 ms
345,856 KB
testcase_08 AC 1 ms
13,764 KB
testcase_09 AC 1 ms
6,816 KB
testcase_10 AC 113 ms
22,824 KB
testcase_11 TLE -
testcase_12 AC 37 ms
8,192 KB
testcase_13 TLE -
testcase_14 AC 13 ms
9,088 KB
testcase_15 AC 745 ms
60,928 KB
testcase_16 TLE -
testcase_17 AC 1,385 ms
315,392 KB
testcase_18 TLE -
testcase_19 AC 13 ms
6,816 KB
testcase_20 AC 54 ms
12,928 KB
testcase_21 TLE -
testcase_22 TLE -
testcase_23 TLE -
testcase_24 AC 1,466 ms
62,720 KB
testcase_25 TLE -
testcase_26 AC 936 ms
297,344 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: variable does not need to be mutable
  --> src/main.rs:21:13
   |
21 |           let mut s = {
   |               ----^
   |               |
   |               help: remove this `mut`
...
67 | /     input! {
68 | |         n: usize,
69 | |         d: usize,
70 | |         k: usize,
71 | |     }
   | |_____- in this macro invocation
   |
   = note: `#[warn(unused_mut)]` on by default
   = note: this warning originates in the macro `input` (in Nightly builds, run with -Z macro-backtrace for more info)

ソースコード

diff #

use modint::ModInt;
#[allow(unused_imports)]
use std::io::Write;

// {{{1
#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

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

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

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

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

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

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

// }}}

fn main() {
    input! {
        n: usize,
        d: usize,
        k: usize,
    }

    let mut solve = Solve {
        d,
        memo: vec![vec![None; d * n + 1]; n + 1],
    };
    println!("{}", solve.solve(n, k).0);
}

struct Solve {
    d: usize,
    memo: Vec<Vec<Option<ModInt>>>,
}

impl Solve {
    fn solve(&mut self, n: usize, k: usize) -> ModInt {
        if let Some(a) = self.memo[n][k] {
            return a
        }

        if n == 0 {
            if k == 0 {
                let ret = ModInt::from(1);
                self.memo[n][k] = Some(ret);
                return ret
            } else {
                let ret = ModInt::from(0);
                self.memo[n][k] = Some(ret);
                return ret
            }
        }

        let mut ret: ModInt = 0.into();
        for i in 1..=self.d {
            if k >= i {
                ret += self.solve(n - 1, k - i);
            }
        }
        self.memo[n][k] = Some(ret);
        ret
    }
}


mod modint {
    use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};

    pub const MODULO: usize = 1_000_000_007;
    // pub const MODULO: usize = 11;

    fn positive_rem(a: isize, b: usize) -> usize {
        let b = b as isize;
        let mut value = a % b;
        if value < 0 {
            value += b;
        }
        // TODO: TryFrom
        value as usize
    }

    /// Return (x, y) s.t. ax + by = d where d = gcd(a, b)
    #[allow(unused)]
    pub fn ext_gcd(a: usize, b: usize) -> (isize, isize) {
        if b == 0 {
            return (1, 0);
        }

        let q = (a / b) as isize;
        let r = a % b;
        let (x1, y1) = ext_gcd(b, r);
        (y1, x1 - q * y1)
    }

    #[derive(Debug, Copy, Clone)]
    pub struct ModInt(pub usize);

    impl From<usize> for ModInt {
        fn from(n: usize) -> ModInt {
            ModInt(n % MODULO)
        }
    }

    impl From<isize> for ModInt {
        fn from(n: isize) -> ModInt {
            // TODO: use TryFrom
            ModInt(positive_rem(n, MODULO as usize))
        }
    }

    impl From<i32> for ModInt {
        fn from(n: i32) -> ModInt {
            // TODO: use TryFrom
            ModInt(positive_rem(n as isize, MODULO as usize))
        }
    }

    impl ModInt {
        #[allow(unused)]
        pub fn pow(self, p: usize) -> ModInt {
            if self == ModInt::from(0) {
                return ModInt::from(0);
            }
            if p == 0 {
                return ModInt::from(1);
            }

            if p % 2 == 0 {
                let half = self.pow(p / 2);
                half * half
            } else {
                self.pow(p - 1) * self
            }
        }

        // when MODULO is prime
        #[allow(unused)]
        pub fn inv(self) -> ModInt {
            let (x, _) = ext_gcd(self.0 as usize, MODULO as usize);
            ModInt::from(x)
        }
    }

    impl Add for ModInt {
        type Output = ModInt;

        fn add(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 + other.0)
        }
    }

    impl Sub for ModInt {
        type Output = ModInt;

        fn sub(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 as isize - other.0 as isize)
        }
    }

    impl Mul for ModInt {
        type Output = ModInt;

        fn mul(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 * other.0)
        }
    }

    impl Neg for ModInt {
        type Output = ModInt;

        fn neg(self) -> Self::Output {
            ModInt::from(0) - self
        }
    }

    impl AddAssign for ModInt {
        fn add_assign(&mut self, other: Self) {
            *self = *self + other;
        }
    }

    impl MulAssign for ModInt {
        fn mul_assign(&mut self, other: Self) {
            *self = *self * other;
        }
    }

    impl SubAssign for ModInt {
        fn sub_assign(&mut self, other: Self) {
            *self = *self - other;
        }
    }

    impl PartialEq for ModInt {
        fn eq(&self, &other: &Self) -> bool {
            self.0 == other.0
        }
    }

    impl Eq for ModInt {}

    #[derive(Debug)]
    pub struct ModIntUtil {
        factorial: Vec<ModInt>,
        factorial_inv: Vec<ModInt>,
        inv: Vec<ModInt>,
    }

    impl ModIntUtil {
        #[allow(unused)]
        pub fn new() -> ModIntUtil {
            ModIntUtil {
                factorial: vec![ModInt::from(1), ModInt::from(1)],
                factorial_inv: vec![ModInt::from(1), ModInt::from(1)],
                inv: vec![ModInt::from(0), ModInt::from(1)],
            }
        }

        fn calc_cache(&mut self, n: usize) {
            let len = self.factorial.len();
            if len < n + 1 {
                for i in len..(n + 1) {
                    let prev = *self.factorial.last().unwrap();
                    self.factorial.push(prev * ModInt::from(i));

                    let inv_i = -self.inv[MODULO % i] * ModInt::from(MODULO / i);
                    self.inv.push(inv_i);

                    let prev = *self.factorial_inv.last().unwrap();
                    self.factorial_inv.push(prev * self.inv[i]);
                }
            }
        }

        #[allow(unused)]
        pub fn factorial(&mut self, n: usize) -> ModInt {
            self.calc_cache(n);
            self.factorial[n]
        }

        #[allow(unused)]
        pub fn factorial_inv(&mut self, n: usize) -> ModInt {
            self.calc_cache(n);
            self.factorial_inv[n]
        }

        // when MODULO is prime
        #[allow(unused)]
        pub fn binom_coef(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }

            self.calc_cache(n);
            self.factorial[n] * self.factorial_inv[k] * self.factorial_inv[n - k]
        }

        #[allow(unused)]
        fn perm(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }
            self.factorial(n) * self.factorial_inv(n - k)
        }

        // Not tested!!
        #[allow(unused)]
        pub fn multi_coef(&mut self, v: &[usize]) -> ModInt {
            let n = v.iter().sum();
            self.calc_cache(n);

            let mut ret = ModInt::from(1);
            ret *= self.factorial[n];
            for v_i in v {
                ret *= self.factorial_inv[*v_i];
            }

            ret
        }
    }
}
0