結果

問題 No.695 square1001 and Permutation 4
ユーザー koba-e964
提出日時 2023-03-29 23:21:26
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 1,463 ms / 7,000 ms
コード長 3,664 bytes
コンパイル時間 13,746 ms
コンパイル使用メモリ 383,220 KB
実行使用メモリ 40,896 KB
最終ジャッジ日時 2024-09-21 14:13:28
合計ジャッジ時間 17,814 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 12
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
($($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)*}
};
}
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)*}
};
}
macro_rules! read_value {
($next:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
};
($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error"));
}
// Verified by: https://yukicoder.me/submissions/706484
fn ext_gcd(a: i128, b: i128) -> (i128, i128, i128) {
if b == 0 {
return (a, 1, 0);
}
let r = a % b;
let q = a / b;
let (g, x, y) = ext_gcd(b, r);
(g, y, x - q * y)
}
fn inv_mod(a: i128, b: i128) -> i128 {
let (_, mut x, _) = ext_gcd(a, b);
x %= b;
if x < 0 {
x += b;
}
x
}
// gcd(rm[i].1, rm[j].1) == 1 for i != j
// Ref: https://www.creativ.xyz/ect-gcd-crt-garner-927/
// O(n^2)
fn garner(rm: &[(i128, i128)], mo: i128) -> i128 {
let n = rm.len();
let mut x_mo = (rm[0].0 % rm[0].1) % mo;
let mut mp_mo = 1;
let mut coef = Vec::with_capacity(n);
coef.push(rm[0].0 % rm[0].1);
for i in 1..n {
let (r, m) = rm[i];
let r = r % m;
let mut mp_mi = 1;
let mut x_mi = 0;
mp_mo = mp_mo * (rm[i - 1].1 % mo) % mo;
for j in 0..i {
x_mi = (x_mi + mp_mi * (coef[j] % m)) % m;
mp_mi = mp_mi * (rm[j].1 % m) % m;
}
let t = (r - x_mi + m) % m * inv_mod(mp_mi, m) % m;
x_mo = (x_mo + t % mo * mp_mo) % mo;
coef.push(t);
}
x_mo
}
fn zadd(a: i32, b: i32, c: i32) -> i32 {
let mut x = a + b;
if x >= c {
x -= c;
}
x
}
fn calc(n: usize, x: &[usize], mo: i32) -> i32 {
let n2 = (n + 1) / 2;
let mut dp = vec![0i32; n2];
dp[0] = 1;
for i in 1..n2 {
let mut tmp = 0;
for &x in x {
if i >= x {
tmp = zadd(tmp, dp[i - x], mo);
}
}
dp[i] = tmp;
}
let mut res = 0i64;
for &x in x {
for i in 0..n2 {
if n - i - 1 >= x && n - i - 1 - x < n - n2 {
res += dp[i] as i64 * dp[n - i - 1 - x] as i64;
res %= mo as i64;
}
}
}
res as i32
}
// https://yukicoder.me/problems/no/695 (4, )
// 10^{17} + 7 = 17×9920467×592951213 ( 3 )
// 1 4 20M * 4B = 80MB
// DP DP
fn main() {
input! {
n: usize, m: usize,
x: [usize; m],
}
let mo = [17, 9920467, 592951213];
let mut res = [(0, 0); 3];
let mut prod = 1i128;
for i in 0..3 {
res[i] = (calc(n, &x, mo[i]) as i128, mo[i] as i128);
prod *= mo[i] as i128;
}
let res = garner(&res, prod);
println!("{}", res);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0