【题解】最大公约数

题目描述

  Mirko刚学会了如何求两个整数A和B的最大公约数。
  由于A和B都非常大,所以我们不能直接给出,我们知道A是由N个正整数相乘得到的,我们也知道B是由M个正整数相乘得到的。
  你的任务就是求A和B的最大公约数。
  如果最大公约数超过9位,那么你只需要结果的后9位即可(如果后9位有前导0,则不需要输出前导0)。

输入输出格式

输入格式

  第一行,一个整数N。(1 ≤ N ≤ 1000)。
  第二行,N个正整数,这N个整数的乘积就等于A。每个正整数的范围:【1,1000000000】.
  第三行,一个整数M。(1 ≤ M ≤ 1000)。
  第四行,M个正整数,这M个整数的乘积就等于B。每个正整数的范围:【1,1000000000】.

输出格式

  A和B的最大公约数。如果超过9位,输出后9位数字,如果后9位有前导0,则不需要输出前导0。

输入输出样例

输入样例

3
358572 83391967 82
3
50229961 1091444 8863

输出样例

12028

题解

  这题a和b很大,所以不能直接用gcd。

  我们知道,给定一个大于1的正整数$a$,满足$a=\prod_{i=1}^{k}b_{i}^{p^{i}}$,那么我们可以分解题目中的a和b的质因数来求gcd。

#include <iostream>
#include <algorithm>

#define MAX_N (1000 + 5)
#define MAX_M (1000 + 5)
#define SQRT 32000

using namespace std;

const int mod = 1000000000;
int n, m;
int p[SQRT], cnt;
int f[SQRT];
int a[SQRT], b[SQRT];
int c[MAX_N], d[MAX_M], totc, totd;
int ans = 1;

int main()
{
    for(register int i = 2; i <= SQRT; ++i)
    {
        if(f[i] ^ 1) p[++cnt] = i;
        for(register int j = 1; p[j] * i <= SQRT; ++j)
        {
            f[p[j] * i] = 1;
            if(!(i % p[j])) break;
         }
    }
    int tmp;
    cin >> n;
    for(register int i = 1; i <= n; ++i)
    {
        cin >> tmp;
        for(register int j = 1; j <= cnt && p[j] <= tmp; ++j)
        {
            while(!(tmp % p[j]))
            {
                tmp /= p[j];
                ++a[p[j]];
            }
        }
        if(tmp != 1) c[++totc] = tmp;
    }
    cin >> m;
    for(register int i = 1; i <= m; ++i)
    {
        cin >> tmp;
        for(register int j = 1; j <= cnt && p[j] <= tmp; ++j)
        {
            while(!(tmp % p[j]))
            {
                tmp /= p[j];
                ++b[p[j]];
            }
        }
        if(tmp != 1) d[++totd] = tmp;
    }
    for(register int i = 2; i <= SQRT; ++i)
    {
        for(register int j = min(a[i], b[i]); j; --j)
        {
            ans = (long long)ans * i % mod;
        }
    }
    sort(c + 1, c + totc + 1);
    sort(d + 1, d + totd + 1);
    for(register int i = 1, j = 1; i <= totc && j <= totd;)
    {
        if(c[i] < d[j]) ++i;
        else if(c[i] > d[j]) ++j;
        else ans = (long long)ans * c[i++] % mod, ++j;
    }
    cout << ans;
    return 0;
}
参考程序

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10585141.html
今日推荐