結果
問題 | No.1011 Infinite Stairs |
ユーザー | tzyvrn |
提出日時 | 2020-03-21 00:46:33 |
言語 | Rust (1.77.0 + proconio) |
結果 |
AC
|
実行時間 | 559 ms / 2,000 ms |
コード長 | 7,804 bytes |
コンパイル時間 | 11,932 ms |
コンパイル使用メモリ | 403,448 KB |
実行使用メモリ | 425,728 KB |
最終ジャッジ日時 | 2024-07-17 11:56:44 |
合計ジャッジ時間 | 16,904 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,812 KB |
testcase_01 | AC | 1 ms
6,820 KB |
testcase_02 | AC | 18 ms
15,232 KB |
testcase_03 | AC | 378 ms
281,088 KB |
testcase_04 | AC | 559 ms
425,600 KB |
testcase_05 | AC | 549 ms
425,728 KB |
testcase_06 | AC | 1 ms
6,940 KB |
testcase_07 | AC | 72 ms
51,840 KB |
testcase_08 | AC | 1 ms
6,944 KB |
testcase_09 | AC | 1 ms
6,940 KB |
testcase_10 | AC | 20 ms
16,128 KB |
testcase_11 | AC | 240 ms
176,896 KB |
testcase_12 | AC | 9 ms
8,320 KB |
testcase_13 | AC | 124 ms
93,568 KB |
testcase_14 | AC | 10 ms
9,600 KB |
testcase_15 | AC | 85 ms
60,928 KB |
testcase_16 | AC | 386 ms
295,680 KB |
testcase_17 | AC | 413 ms
315,520 KB |
testcase_18 | AC | 169 ms
126,208 KB |
testcase_19 | AC | 4 ms
6,940 KB |
testcase_20 | AC | 16 ms
13,056 KB |
testcase_21 | AC | 92 ms
68,992 KB |
testcase_22 | AC | 351 ms
265,856 KB |
testcase_23 | AC | 87 ms
65,280 KB |
testcase_24 | AC | 84 ms
63,360 KB |
testcase_25 | AC | 167 ms
125,440 KB |
testcase_26 | AC | 42 ms
32,128 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)
ソースコード
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 mx = d * n; // dp[i][j] = i回目にj段目にいるパターン let mut dp = vec![vec![ModInt::from(0); mx + 1]; n + 1]; let mut csum = vec![vec![ModInt::from(0)]; n + 1]; dp[0][0] = 1.into(); for j in 0..=mx { let tmp = csum[0][j] + dp[0][j]; csum[0].push(tmp); } for i in 1..=n { for j in 0..=mx { // dp[i][j] = dp[i - 1][j - d] + ... + dp[i - 1][j - 1] if j >= d { dp[i][j] = csum[i - 1][j] - csum[i - 1][j - d]; } else { dp[i][j] = csum[i - 1][j]; } } for j in 0..=mx { let tmp = csum[i][j] + dp[i][j]; csum[i].push(tmp); } } println!("{}", dp[n][k].0); } 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 } } }