https://atcoder.jp/contests/abc340/tasks/abc340_f
を解くだけですが、けっこういやらしいですね。
// F - S = 1 #![allow(non_snake_case)] use std::cmp::min; //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>().split_whitespace() .map(|e| e.parse().ok().unwrap()).collect() } // ax = by + 1 (a, b > 0) fn linear_diophantine(a: i64, b: i64) -> Option<(i64, i64)> { if a == 1 { return Some((1, 0)) } let q = b / a; let r = b % a; if r == 0 { return None } let (x1, y1) = linear_diophantine(r, a)?; Some((-q * x1 - y1, -x1)) } //////////////////// process //////////////////// fn read_input() -> (i64, i64) { let v: Vec<i64> = read_vec(); let (X, Y) = (v[0], v[1]); (X, Y) } fn shift_core(a: i64, b: i64, X: i64, Y: i64) -> (i64, i64) { let mut min_e = min(a.abs(), b.abs()); let (mut a1, mut b1) = (a, b); loop { a1 += X; b1 += Y; if min(a1.abs(), b1.abs()) >= min_e { a1 -= X; b1 -= Y; break } min_e = min(a1.abs(), b1.abs()); } let (mut a2, mut b2) = (a, b); loop { a2 -= X; b2 -= Y; if min(a2.abs(), b2.abs()) >= min_e { break } min_e = min(a2.abs(), b2.abs()); a1 = a2; b1 = b2 } (a1, b1) } const D: i64 = 10_i64.pow(18); fn select((A1, B1): (i64, i64), (A2, B2): (i64, i64)) -> Option<(i64, i64)> { let min1 = min(A1.abs(), B1.abs()); let min2 = min(A2.abs(), B2.abs()); if min1 > D { if min2 > D { None } else { Some((A2, B2)) } } else { if min1 < min2 { Some((A1, B1)) } else { Some((A2, B2)) } } } fn XOR(b1: bool, b2: bool) -> bool { b1 != b2 } fn shift(a: i64, b: i64, X: i64, Y: i64) -> Option<(i64, i64)> { if XOR(X > 0, Y > 0) { // different sign select(shift_core(a, -b, X, Y), shift_core(-a, b, X, Y)) } else { select(shift_core(a, b, X, Y), shift_core(-a, -b, X, Y)) } } fn F_core(X: i64, Y: i64) -> Option<(i64, i64)> { if Y == 0 { if X.abs() <= 2 { return Some((0, 2 / X)) } else { return None } } else if X == 0 { if Y.abs() <= 2 { return Some((2 / Y, 0)) } else { return None } } else if X % 2 == 0 && Y % 2 == 0 { let (a, b) = linear_diophantine(Y.abs()/2, X.abs()/2)?; shift(a, b, X, Y) } else { let (a, b) = linear_diophantine(Y.abs(), X.abs())?; shift(a*2, b*2, X, Y) } } fn F(X: i64, Y: i64) { if let Some((A, B)) = F_core(X, Y) { println!("{} {}", A, B) } else { println!("-1") } } fn main() { let (X, Y) = read_input(); F(X, Y) }