公式

I - S = 1 解説 by Nyaan


まず、重要な事実として、\((0, 0), (X, Y), (A, B)\) を頂点とする三角形の面積は \(\frac{\vert AY - BX \vert}{2}\) です。よってこの問題は、\(X, Y\) が与えられたときに

\[\vert AY - BX \vert = 2\]

を満たす整数の組 \((A, B)\) を発見する問題であると言い換えられます。

この問題の解き方を説明します。以下では \(g = \gcd(X, Y)\) とします。 (注 : \(\gcd(a, b)\)\(\vert a \vert\)\(\vert b \vert\) の最大公約数として定義しています。)
まず、\(g\)\(3\) 以上の場合は \(AY - BX\)\(g\) の倍数となるため答えは存在しません。
\(g = 1, 2\) の場合は拡張ユークリッドの互除法と呼ばれるアルゴリズムを利用することで常に解を得ることが出来ます。 拡張ユークリッドの互除法とは、整数の組 \((a, b)\) を入力として与えたときに以下の手順によって\(ax + by = \pm \mathrm{gcd}(a, b)\) となる整数の組 \((x, y)\)\(\mathrm{O}(\log \min(|a|, |b|))\) で計算するアルゴリズムです。(ここで整数の組 \(x, y\)\(\max(|x|, |y|) \leq \max(|a|, |b|)\) を満たす整数であることが保証されています。)

// 拡張ユークリッドの互除法の実装例
pair<long long, long long> extgcd(long long a, long long b) {
  if (b == 0) return make_pair(1, 0);
  long long x, y;
  tie(y, x) = extgcd(b, a % b);
  y -= a / b * x;
  return make_pair(x, y);
}

拡張ユークリッドの互除法に \((Y, -X)\) を入力することで、返り値を \((c, d)\) として

\[cY - dX = \pm g\]

かつ \(\vert c \vert, \vert d \vert \leq 10^{17}\) を満たす \((c, d)\) の組を得ることが出来ます。求めたいものは \(AY - BX =\pm 2\) を満たす\((A, B)\) の組で、これは \((c, d)\)\(\frac{2}{g}\) 倍することで得ることが出来ます。この \((A, B)\)\(\vert A \vert, \vert B \vert \leq 10^{18}\) という制約を満たしており問題ないです。

以上よりこの問題を解くことが出来ました。計算量は \(\mathrm{O}(\log \min (X, Y))\) 程度で十分高速です。

投稿日時:
最終更新: