UVA11889 Benefit
题目大意
给定正整数 $a,c$,求使 $\operatorname{lcm}(a,b)=c$ 成立最小的 $b$,若没有满足条件的 $b$,输出 NO SOLUTION
。
思路分析
我们知道,
$$\operatorname{lcm}(a,b)=\prod p_i^{\max(k_{a_i},k_{b_i})}$$
将 $c$ 分解质因数,也可以得到
$$c=\prod p_i^{k_{c_i}}$$
要使 $\operatorname{lcm}(a,b)=c$,代入一下得到
$$\prod p_i^{k_{c_i}}=\prod p_i^{\max(k_{a_i},k_{b_i})}$$
即对于每一个质数 $p_i$,有
$$k_{c_i}=\max(k_{a_i},k_{b_i})$$
因为我们已经知道 $k_{c_i}$ 和 $k_{a_i}$,只要求出满足条件的最小的 $k_{b_i}$ 就可以了。记住“最小的”这三个字。
我们分类讨论一下:
-
当 $k_{c_i} < k_{a_i}$ 时:
显然 $\max(k_{a_i},k_{b_i}) > k_{c_i}$。
输出
NO SOLUTION
。 -
当 $k_{c_i} > k_{a_i}$ 时:
要想使其成立,必须使 $k_{b_i}=k_{c_i}$。
-
当 $k_{c_i} = k_{a_i}$ 时:
因为 $k_{b_i}$ 是非负整数,所以我们将 $k_{b_i}$ 取最小值 $0$ 即可。
实际上,分解质因数我们可以先把每个数的最小质因数提前筛出来,然后 $O(\log n)$ 求解就可以了。因为最后求 $b$ 的循环里面套了一个快速幂,所以总时间复杂度 $O(t\log^2n)$,足以通过此题。
本题坑点
在最后处理 $b$ 的时候一定要记得把没有在 $a$ 的质因数里出现但是在 $c$ 的质因数里出现的数乘上去。
完整代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef map<int, int>::iterator iter;
const int maxn = 1e5 + 1;
const int maxm = 1e7 + 1;
int prime[maxm], cnt;
bool book[maxm];
int fc[maxm];
void sieve() {
for (int i = 2; i < maxm; i++) {
if (!book[i]) {
prime[++cnt] = i;
fc[i] = i;
}
for (int j = 1; j <= cnt && i * prime[j] < maxm; j++) {
book[i * prime[j]] = true;
fc[i * prime[j]] = prime[j];
if (i % prime[j] == 0) break;
}
}
}
int power(int base, int freq) {
int ans = 1, tmp = base;
while (freq > 0) {
if (freq % 2 == 1) ans = ans * tmp;
freq /= 2;
tmp = tmp * tmp;
}
return ans;
}
int t, a, c, b = 1;
map<int, int> sa;
map<int, int> sc;
signed main() {
cin >> t;
while (t--) {
sa.clear();
sc.clear();
bool fl = true;
cin >> a >> c;
b = 1;
while (a != 1) {
if (sa.count(fc[a])) sa[fc[a]]++;
else sa[fc[a]] = 1;
a /= fc[a];
}
while (c != 1) {
if (sc.count(fc[c])) sc[fc[c]]++;
else sc[fc[c]] = 1;
c /= fc[c];
}
for (iter i = sa.begin(); i != sa.end(); i++) {
if (!sc.count(i->first) || sc[i->first] < i->second) {
fl = false;
break;
}
if (sc[i->first] == i->second) {
sc[i->first] = 0;
continue;
}
b *= power(i->first, sc[i->first]);
sc[i->first] = 0;
}
for (iter i = sc.begin(); i != sc.end(); i++) {
b *= power(i->first, i->second);
}
if (!fl) {
cout << "NO SOLUTION" << endl;
continue;
}
cout << b << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现