0829-T3 公因数
0829-T3 公因数
题意
给定一个长度为
每次操作选择两个数
求经过若干次操作后序列最大公因数的最大值,以及此情况下操作的最小次数。
思路
每次操作不会改变序列总共的质因数和次数。
想要最大公因数最大,必须让质因数的次数平均分配给每个数。
现将每个数都质因数分解,次数加起来。
容易发现每个质因数的次数
对于操作次数,如果
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, a[N], c[N], ans1 = 1, ans2;
int q[N], tot, b[N];
int qpow(int a, int p) {
int res = 1;
for (; p; p >>= 1, a *= a)
if (p & 1) res *= a;
return res;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1, t; i <= n; i ++) {
t = a[i];
for (int j = 2; j * j <= a[i]; j ++) {
if (t % j) continue;
if (!c[j]) q[++ tot] = j;
while (t % j == 0) t /= j, c[j] ++;
}
if (t != 1) {
if (!c[t]) q[++ tot] = t;
c[t] ++;
}
}
for (int i = 1; i <= tot; i ++) c[q[i]] /= n;
for (int i = 1; i <= tot; i ++) ans1 *= qpow(q[i], c[q[i]]);
for (int i = 1, t; i <= n; i ++) {
t = a[i];
for (int j = 2; j * j <= a[i]; j ++) {
if (t % j) continue;
while (t % j == 0) t /= j, b[j] ++;
}
if (t != 1) b[t] ++;
for (int j = 1; j <= tot; j ++) ans2 += max(0, c[q[j]] - b[q[j]]);
t = a[i];
for (int j = 2; j * j <= a[i]; j ++) {
if (t % j) continue;
while (t % j == 0) t /= j, b[j] --;
}
if (t != 1) b[t] --;
}
cout << ans1 << " " << ans2 << "\n";
return 0;
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/18387436,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】