けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

Chokudai SpeedRun 002 J - GCD β (500 点)

「探索候補は実はそう多くない」という教育的問題!!!

問題へのリンク

問題概要

 N 組の整数ペア  (A_i, B_i) がある。各ペアから整数をどちらかを選ぶ。こうして選ばれた  N 個の整数の最大公約数の最大値を求めよ。

制約

  •  1 \le N \le 5 \times 10^{5}

考えたこと

約数と言われて思い浮かべるべきことの一つとして「約数はそれほど多くない」というのがあると思う。標語的に

  •  10^{9} 以下の整数の約数の個数は最大でも 1333 個くらい

というのがある。というわけで今回の問題もそんな感じで、とりあえず

  •  A_1 の約数と  B_1 の約数を集めたもの

が答えの候補になる。これを全部調べれば OK。

#include <iostream>
#include <vector>
using namespace std;
using pint = pair<int,int>;

vector<long long> calc_divisor(long long n) {
    vector<long long> res;
    for (long long i = 1LL; i*i <= n; ++i) {
        if (n % i == 0) {
            res.push_back(i);
            long long j = n / i;
            if (j != i) res.push_back(j);
        }
    }
    sort(res.begin(), res.end());
    return res;
}
 
int main() {  
    int N; cin >> N;
    vector<long long> A(N), B(N);
    for (int i = 0; i < N; ++i) cin >> A[i] >> B[i];

    auto alt = calc_divisor(A[0]);
    auto blt = calc_divisor(B[0]);
    for (auto v : blt) alt.push_back(v);
 
    long long ma = 1;
    for (auto v : alt) {
        bool ok = true;
        for (int i = 0; i < N; ++i) {
            if (A[i] % v != 0 && B[i] % v != 0) ok = false;
        }
        if (ok) ma = max(ma, v);
    }
    cout << ma << endl;
}