結果
| 問題 |
No.187 中華風 (Hard)
|
| コンテスト | |
| ユーザー |
fukafukatani
|
| 提出日時 | 2020-09-20 15:38:14 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,396 bytes |
| コンパイル時間 | 12,842 ms |
| コンパイル使用メモリ | 379,292 KB |
| 実行使用メモリ | 6,948 KB |
| 最終ジャッジ日時 | 2024-06-24 10:46:00 |
| 合計ジャッジ時間 | 14,127 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 5 WA * 20 |
ソースコード
#![allow(unused_imports)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;
use std::ops::Bound::*;
#[allow(unused_macros)]
macro_rules! debug {
($($e:expr),*) => {
#[cfg(debug_assertions)]
$({
let (e, mut err) = (stringify!($e), std::io::stderr());
writeln!(err, "{} = {:?}", e, $e).unwrap()
})*
};
}
fn main() {
let n = read::<usize>();
let mut r = vec![0; n];
let mut m = vec![0; n];
for i in 0..n {
let v = read_vec::<i64>();
r[i] = v[0];
m[i] = v[1];
}
if let Some((mut x, y)) = crt(&r, &m) {
if x == 0 {
x += y;
}
println!("{}", x);
} else {
println!("-1");
}
}
fn read<T: std::str::FromStr>() -> T {
let mut s = String::new();
std::io::stdin().read_line(&mut s).ok();
s.trim().parse().ok().unwrap()
}
fn read_vec<T: std::str::FromStr>() -> Vec<T> {
read::<String>()
.split_whitespace()
.map(|e| e.parse().ok().unwrap())
.collect()
}
pub fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
let a = a.rem_euclid(b);
if a == 0 {
return (b, 0);
}
let mut s = b;
let mut t = a;
let mut m0 = 0;
let mut m1 = 1;
while t != 0 {
let u = s / t;
s -= t * u;
m0 -= m1 * u;
std::mem::swap(&mut s, &mut t);
std::mem::swap(&mut m0, &mut m1);
}
if m0 < 0 {
m0 += b / s;
}
(s, m0)
}
// return y (mod z)
pub fn crt(r: &[i64], m: &[i64]) -> Option<(i64, i64)> {
assert_eq!(r.len(), m.len());
// Contracts: 0 <= r0 < m0
let (mut r0, mut m0) = (0, 1);
for (&(mut ri), &(mut mi)) in r.iter().zip(m.iter()) {
assert!(1 < mi);
ri = ri.rem_euclid(mi);
if m0 < mi {
std::mem::swap(&mut r0, &mut ri);
std::mem::swap(&mut m0, &mut mi);
}
if m0 % mi == 0 {
if r0 % mi != ri {
return None;
}
continue;
}
let (g, im) = inv_gcd(m0, mi);
let u1 = mi / g;
// |ri - r0| < (m0 + mi) <= lcm(m0, mi)
if (ri - r0) % g != 0 {
return None;
}
let x = (ri - r0) / g % u1 * im % u1;
r0 += x * m0;
m0 *= u1; // -> lcm(m0, mi)
if r0 < 0 {
r0 += m0
};
}
Some((r0, m0))
}
fukafukatani