Official

072 - Max GCD 2 Editorial by tatyam


ありうる \((x, y)\) の組は最大で \(2 \times 10^{10}\) 個程度になるため、全ての \((x, y)\) の組に対して \(\gcd\) を求めることはできません。
そこで、答えの方を \(c\) と固定し、「\(\gcd(x, y) = c\) となる \((x, y)\) の組は存在するか?」という判定問題を考えます。

最大公約数ですから、\(x, y\)\(c\) の倍数でなければなりません。逆に、区間 \([A, B]\)\(2\) 個以上 \(c\) の倍数が存在すれば、\(\gcd(x, y) = c\) となる \((x, y)\) を選ぶことができます。( 連続する \(c\) の倍数を選べば良い )

\(B ≤ 2 \times 10^5\) なので、\(c = 1, 2, \dots, B\) のそれぞれについて、区間 \([A, B]\)\(2\) 個以上 \(c\) の倍数が存在するか判定することで、十分高速にこの問題を解くことができます。


\(A\) 以上 \(B\) 以下の \(c\) の倍数の数は、
( \(A\) 以上 \(B\) 以下の \(c\) の倍数の数 )\({}={}\)( \(1\) 以上 \(B\) 以下の \(c\) の倍数の数 )\({}-{}\)( \(1\) 以上 \(A - 1\) 以下の \(c\) の倍数の数 )\({}=\left\lfloor\dfrac Bc\right\rfloor - \left\lfloor\dfrac {A - 1}c\right\rfloor\)
と計算できます。

あるいは、\(2\) 個以上あるかどうかのみを確かめれば良いので、\(\left\lceil\dfrac Ac\right\rceil < \left\lfloor\dfrac Bc\right\rfloor\) でも判定ができます。

回答例 (C++)

#include <iostream>
using namespace std;

int main(){
    int A, B;
    cin >> A >> B;
    for(int c = B; ; c--) if((A + c - 1) / c < B / c){
        cout << c << endl;
        return 0;
    }
}

回答例 (Python)

A, B = map(int, input().split())
for c in range(B, 0, -1):
    if (A + c - 1) // c < B // c:
        exit(print(c))

posted:
last update: