题解AT_abc142_d

shaozhehan

2023-04-01 21:02:49

Solution

[原题链接](https://www.luogu.com.cn/problem/AT_abc142_d) [AtCoder 链接](https://atcoder.jp/contests/abc142/tasks/abc142_d) 题目大意: 给定两个数 $a$ 和 $b$,问你可以选出多少个数使得每一个数都能整除 $a$ 和 $b$,且数两两互质。 思路: 我们可以先算出 $\gcd(a,b)$,每一个满足要求的数都必然整除 $\gcd(a,b)$。显然,我们可以把 $\gcd(a,b)$ 分解质因数,再把质因数个数加上 $1$,也就是选 $1$,最终输出。 下证这种情况是最优解: 假设有两个数 $x$ 和 $y$,均能整除 $\gcd(a,b)$。如果现在有两个数 $m$ 和 $mn$ 可以选择,显然 $\gcd(m,x)$ 整除 $\gcd(mn,x)$,所以选择 $m$ 比选择 $mn$ 好。 坑点: 1. ```gcd``` 函数需要开 ```long long```! 1. 枚举质因数的时候循环变量要用 ```long long``` 或强制转换成 ```long long``` 类型,否则会炸精度! 1. 不要忘记 $1$ 也要选上! 上代码: ```cpp #include <iostream> using namespace std; long long gcd(const long long &x, const long long &y){// gcd 函数模板(坑点1:long long 类型) return (x % y == 0 ? y : gcd(y, x % y)); } int main(){ cin.tie(NULL); cout.tie(NULL); ios::sync_with_stdio(false);// cin、cout 加速 long long a, b; cin >> a >> b; long long temp = gcd(a, b); int cnt = 0; // 分解质因数,统计质因数个数 for (int i = 2; 1ll * i * i <= temp; i++){// 坑点 2:循环变量 if (temp % i == 0){ cnt++; while (temp % i == 0){ temp /= i; } } } if (temp != 1){// 如果还有剩余的质因数,那么 cnt 再加上 1 cnt++; } cout << cnt + 1 << "\n";// 坑点 3:1 也要算上 return 0; } ```