1 条题解
-
0
题目大意
已知 是一个在 范围内的整数, 和 是 的两个最大约数(即除了 本身之外最大的两个约数),且满足 。给定 和 ,求一个满足条件的 。若有多解,输出任意一个。
解题思路
设 的所有约数从小到大排列为:
其中真约数为 。已知最大的两个真约数是 和 ,即 ,。
我们根据 是否能被 整除,分两种情况讨论。
情况一:
若 是 的倍数,那么存在整数 ,使得 。
由于 是小于 的最大约数,且 是次大约数,它们必须满足:
- 是 的最大真约数;
- 是第二大的真约数。
若 能被 整除,则 和 之间不可能再存在其他约数(否则 不是最大真约数)。事实上,可以证明 一定是 的最小质因子。理由如下:
由约数的配对性质:若 是 的约数,则 也是约数。最大真约数 对应的配对约数是 ,它必须是 的最小约数(即最小质因子)。设这个最小质因子为 ,则:
$$\frac{x}{b} = p \quad \Rightarrow \quad x = b \cdot p $$又因为 是次大真约数,且 ,可以验证此时 或者类似的配对关系。实际上,将 代入 ,得:
同时 ,符合两个最大真约数分别为 和 的结构。因此:
结论:当 时,。
情况二:
若 不能被 整除,说明 和 不是简单的倍数关系。此时 至少有两个不同的质因子。
设 的最小质因子为 ,次小质因子为 。由于 是最大真约数,它对应除以最小质因子:
而 是次大真约数,它对应除以次小质因子:
由约数的配对可知, 与 是 的两个最大真约数。那么它们的最大公约数是什么?
$$\gcd(a, b) = \gcd\left(\frac{x}{q}, \frac{x}{p}\right) = \frac{x}{p \cdot q} \quad (\text{因为 } p, q \text{ 互质}) $$从而有:
$$\frac{x}{p \cdot q} = \gcd(a, b) \quad \Rightarrow \quad x = p \cdot q \cdot \gcd(a, b) $$另一方面,由 可得:
$$x = b \cdot p = b \cdot \frac{x}{x/p} = b \cdot \frac{x}{b} $$这并不能直接得到 ,但我们可以用 和 表示 。注意 ,且 ,则:
因此:
结论:当 时,。
算法步骤
- 读入测试用例数 。
- 对于每组测试数据:
- 读入两个正整数 和 。
- 如果 :
- 计算 。
- 否则:
- 计算 。
- 计算 。
- 输出 。
复杂度分析
- 时间复杂度:每个测试用例只需 的 GCD 运算(辗转相除法)。总复杂度 ,在 时完全可行。
- 空间复杂度:。
正确性证明
两种情况均基于约数配对性质严格推导,保证了 和 恰好为 的两个最大真约数。具体证明思路已融入思路部分。
C++ 代码
#include <bits/stdc++.h> using namespace std; using ll = long long; ll my_gcd(ll x, ll y) { return y ? my_gcd(y, x % y) : x; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { ll a, b; cin >> a >> b; if (b % a == 0) { cout << b * (b / a) << "\n"; } else { cout << b * (a / my_gcd(a, b)) << "\n"; } } return 0; }
补充说明
- 在第一种情况中,当 时, 为质数,此时 。例如 ,符合题目要求。
- 在第二种情况中,即使 和 不互质,公式依然成立,因为 提取了公共因子。
- 由于题目保证 是某个 的两个最大真约数,上述公式必定产生整数结果且落在 范围内。
- 1
信息
- ID
- 6493
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者