题解 P7616 [COCI2011-2012#2] ZADAĆA

题目描述

给定 \(n\) 个正整数 \(a_1,a_2,a_3\cdots a_n\)\(m\) 个正整数 \(b_1,b_2,b_3,\cdots b_n\) ,求:

\[\gcd(\prod_{i=1}^n a_i,\prod_{i=1}^n b_i) \]

\(1 \leq n \leq 10^3 ,1 \leq a_i ,b_i \leq 10^9\)

Solution

一般这种两个很大的数字的 \(\gcd\)(比如说本题的 \(n\) 个数字的乘积和 \(m\) 个数字的乘积的 \(\gcd\))用质因数分解求答案。

但是这题 \(n\) 只有 \(1000\),可以考虑 \(\mathcal{O}(n^2 \log n)\) 暴力求解。具体地,对于每个 \(a_i\),遍历一遍所有的 \(b_j\),设 \(\gcd(a_i,b_j)=d\) ,如果 \(d \neq1\) ,那么就让 \(ans \gets ans \times d\),同时让 \(a_i\gets \dfrac{a_i}{d},b_j\times \dfrac{b_j}{d}\)

题目说保留最后 \(9\) 位数字,也就是说在 \(\bmod\ 10^9\) 的意义下进行计算,在 \(ans\gets ans \times d\) 这一步取模就可以。

代码如下:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
typedef long long LL;
using namespace std;
const int N = 1005;
const LL mod = 1e9;
bool flag;
inline int gcd(int a ,int b) {
    return b == 0 ? a : gcd(b ,a % b);
}
int n ,m ,a[N] ,b[N];
LL ans = 1;
signed main() {
    scanf("%d" ,&n);
    for (int i = 1; i <= n; i++) scanf("%d" ,&a[i]);
    scanf("%d" ,&m);
    for (int i = 1; i <= m; i++) scanf("%d" ,&b[i]);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int c = gcd(a[i] ,b[j]);
            if (c != 1) {
                if (ans * c >= mod) flag = true ,ans = ans * c % mod;
                else ans *= c;
                a[i] /= c; b[j] /= c;
            }
        }
    }
    if (flag) printf("%09lld\n" ,ans); //因为要输出最后九位数字,所以需要一个 flag ,并且 printf 格式是 %09lld
    else printf("%lld\n" ,ans);
    return 0;
}

Update on 2021.6.14 :修改了之前的错误。

posted @ 2021-06-15 12:28  recollector  阅读(67)  评论(0编辑  收藏  举报