結果
| 問題 |
No.3310 mod998
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2025-10-23 20:43:21 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 126 ms / 2,000 ms |
| コード長 | 3,157 bytes |
| コンパイル時間 | 11,488 ms |
| コンパイル使用メモリ | 402,024 KB |
| 実行使用メモリ | 8,720 KB |
| 最終ジャッジ日時 | 2025-10-23 20:43:38 |
| 合計ジャッジ時間 | 15,286 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 33 |
ソースコード
// GPT5による生成コード
use std::io::{self, Read};
const MOD: u32 = 998;
const P1: u32 = 2;
const P2: u32 = 499;
const INV2_MOD_499: u32 = 250; // 2 * 250 ≡ 1 (mod 499)
// 十進文字列 s の値を mod で割った余り
fn mod_decimal_str(s: &str, m: u32) -> u32 {
let mut r: u32 = 0;
for b in s.bytes() {
let d = (b - b'0') as u32;
r = (r * 10 + d) % m;
}
r
}
// base^{int(exp_dec)} mod m, exp_dec は十進文字列
fn pow_decimal_exp(mut base: u32, exp_dec: &str, m: u32) -> u32 {
if m == 1 { return 0; }
base %= m;
// precompute base^d (d=0..9)
let mut small = [1u32; 10];
for d in 1..10 {
small[d] = (small[d - 1] * base) % m;
}
let mut res: u32 = 1;
for b in exp_dec.bytes() {
let d = (b - b'0') as usize;
// res = res^10 * base^d
res = mod_pow_u32(res, 10, m);
res = (res * small[d]) % m;
}
res
}
// a^e mod m (e は小さな非負整数、m は 2 or 499)
fn mod_pow_u32(mut a: u32, mut e: u32, m: u32) -> u32 {
let mut r: u32 = 1;
a %= m;
while e > 0 {
if e & 1 != 0 { r = (r as u64 * a as u64 % m as u64) as u32; }
a = (a as u64 * a as u64 % m as u64) as u32;
e >>= 1;
}
r
}
// 幾何級数 S = sum_{i=0}^K N^i (mod p)
fn geom_sum_mod_p(n: u32, k_str: &str, p: u32) -> u32 {
let a = n % p;
if a == (1 % p) {
return (mod_decimal_str(k_str, p) + 1) % p;
}
// S ≡ (a^{K+1} - 1) * (a-1)^{-1} (mod p)
// a^{K+1} = a^{K} * a
let mut t = pow_decimal_exp(a, k_str, p);
t = (t as u64 * a as u64 % p as u64) as u32; // a^{K+1}
t = (t + p - 1) % p; // -1
// p は素数(2, 499)なので (a-1)^{-1} ≡ (a-1)^{p-2}
let inv = mod_pow_u32((a + p - 1) % p, p - 2, p);
(t as u64 * inv as u64 % p as u64) as u32
}
// CRT: x ≡ a2 (mod 2), x ≡ a499 (mod 499) を mod 998 で復元
fn crt_2_499(a2: u32, a499: u32) -> u32 {
// x = a2 + 2 * ((a499 - a2) * inv(2) mod 499)
let t = (a499 + P2 - (a2 % P2)) % P2;
let c = (t as u64 * INV2_MOD_499 as u64 % P2 as u64) as u32;
(a2 + P1 * c) % MOD
}
fn main() {
// 入力全読み
let mut s = String::new();
io::stdin().read_to_string(&mut s).unwrap();
let mut it = s.split_whitespace();
let t: usize = it.next().unwrap().parse().unwrap();
let mut out = String::new();
for _ in 0..t {
let n: u32 = it.next().unwrap().parse().unwrap();
let m: usize = it.next().unwrap().parse().unwrap();
// 早期分岐(n ≡ 0 や n ≡ 1)
let n_mod = n % MOD;
for _ in 0..m {
let k_str = it.next().unwrap(); // 任意長
let ans = if n_mod == 0 {
// 0^0=1、以降0 ⇒ 常に 1
1u32
} else if n_mod == 1 {
(mod_decimal_str(k_str, MOD) + 1) % MOD
} else {
let a2 = geom_sum_mod_p(n, k_str, P1);
let a499 = geom_sum_mod_p(n, k_str, P2);
crt_2_499(a2, a499)
};
out.push_str(&format!("{}\n", ans));
}
}
print!("{}", out);
}