結果
問題 | No.1085 桁和の桁和 |
ユーザー |
![]() |
提出日時 | 2020-06-19 21:53:43 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 20 ms / 2,000 ms |
コード長 | 4,913 bytes |
コンパイル時間 | 27,030 ms |
コンパイル使用メモリ | 378,756 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-11-06 17:33:37 |
合計ジャッジ時間 | 26,777 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 35 |
ソースコード
// ---------- begin ModInt ----------const MOD: u32 = 1_000_000_007;#[derive(Clone, Copy)]struct ModInt(u32);impl std::ops::Add for ModInt {type Output = ModInt;fn add(self, rhs: ModInt) -> Self::Output {let mut d = self.0 + rhs.0;if d >= MOD {d -= MOD;}ModInt(d)}}impl std::ops::AddAssign for ModInt {fn add_assign(&mut self, rhs: ModInt) {*self = *self + rhs;}}impl std::ops::Sub for ModInt {type Output = ModInt;fn sub(self, rhs: ModInt) -> Self::Output {let mut d = self.0 + MOD - rhs.0;if d >= MOD {d -= MOD;}ModInt(d)}}impl std::ops::SubAssign for ModInt {fn sub_assign(&mut self, rhs: ModInt) {*self = *self - rhs;}}impl std::ops::Mul for ModInt {type Output = ModInt;fn mul(self, rhs: ModInt) -> Self::Output {ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)}}impl std::ops::MulAssign for ModInt {fn mul_assign(&mut self, rhs: ModInt) {*self = *self * rhs;}}impl std::ops::Neg for ModInt {type Output = ModInt;fn neg(self) -> Self::Output {ModInt(if self.0 == 0 {0} else {MOD - self.0})}}impl std::fmt::Display for ModInt {fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {write!(f, "{}", self.0)}}impl std::str::FromStr for ModInt {type Err = std::num::ParseIntError;fn from_str(s: &str) -> Result<Self, Self::Err> {let val = s.parse::<u32>()?;Ok(ModInt::new(val))}}impl From<usize> for ModInt {fn from(val: usize) -> ModInt {ModInt((val % MOD as usize) as u32)}}impl From<i64> for ModInt {fn from(val: i64) -> ModInt {let m = MOD as i64;ModInt::new((val % m + m) as u32)}}#[allow(dead_code)]impl ModInt {pub fn new(n: u32) -> ModInt {ModInt(n % MOD)}pub fn zero() -> ModInt {ModInt(0)}pub fn one() -> ModInt {ModInt(1)}pub fn pow(self, mut n: u32) -> ModInt {let mut t = ModInt::one();let mut s = self;while n > 0 {if n & 1 == 1 {t *= s;}s *= s;n >>= 1;}t}pub fn inv(self) -> ModInt {assert!(self.0 > 0);self.pow(MOD - 2)}}// ---------- end ModInt ----------// ---------- begin Precalc ----------#[allow(dead_code)]struct Precalc {inv: Vec<ModInt>,fact: Vec<ModInt>,ifact: Vec<ModInt>,}#[allow(dead_code)]impl Precalc {pub fn new(n: usize) -> Precalc {let mut inv = vec![ModInt::one(); n + 1];let mut fact = vec![ModInt::one(); n + 1];let mut ifact = vec![ModInt::one(); n + 1];for i in 2..(n + 1) {fact[i] = fact[i - 1] * ModInt(i as u32);}ifact[n] = fact[n].inv();if n > 0 {inv[n] = ifact[n] * fact[n - 1];}for i in (1..n).rev() {ifact[i] = ifact[i + 1] * ModInt((i + 1) as u32);inv[i] = ifact[i] * fact[i - 1];}Precalc {inv: inv,fact: fact,ifact: ifact,}}pub fn inv(&self, n: usize) -> ModInt {assert!(n > 0);self.inv[n]}pub fn fact(&self, n: usize) -> ModInt {self.fact[n]}pub fn ifact(&self, n: usize) -> ModInt {self.ifact[n]}pub fn comb(&self, n: usize, k: usize) -> ModInt {if k > n {return ModInt::zero();}self.fact[n] * self.ifact[k] * self.ifact[n - k]}}// ---------- end Precalc ----------use std::io::Read;fn run() {let mut s = String::new();std::io::stdin().read_to_string(&mut s).unwrap();let mut it = s.trim().split_whitespace();let s: Vec<char> = it.next().unwrap().chars().collect();let d: usize = it.next().unwrap().parse().unwrap();let w = 9;let mut dp = vec![ModInt::zero(); w];dp[0] = ModInt::one();let mut zero = true;for c in s {if c == '?' {let mut next = vec![ModInt::zero(); w];for i in 0..w {for j in 0..10 {next[(i + j) % w] += dp[i];}}dp = next;} else {zero &= c == '0';let d = c.to_digit(10).unwrap() as usize % 9;dp.rotate_right(d);}}let ans = if d == 0 {if zero {ModInt::one()} else {ModInt::zero()}} else if d == 9 {dp[0] - if zero {ModInt::one()} else {ModInt::zero()}} else {dp[d]};println!("{}", ans);}fn main() {run();}