题目大意:给出一整数n,将这个数分解成因数的幂的乘积,且这些因数的质因数不能重复,求最大的这些因数与他们的幂指数的乘积之和最大是多少
2<=n<=1e9
思路:因为这些因数的质因数不能重复,所以要想最大,只能将不同的因数乘在一起变成更大的因数例如864==,因为两个数相乘肯定比相加大,2+3<2*3,加上幂指数大小关系不变。
分解质因数只需要O(sqrt(n))的复杂度,因为一个数最多只有一个大于sqrt(n)的质因数,有两个的话相乘就大于了n
//#include<__msvc_all_public_headers.hpp>
#include<bits/stdc++.h>
using namespace std;
pair<int, int>a[100000];
int tot = 0;
int x = 1;
void cal(int n)//分解质因数
{
for (i = 2; i*i <= n; i++)
{//只需遍历到sqrt(n)
bool flag = 0;//当前数字是否是质因数
int cnt = 0;//记录指数
while (n % i == 0)
{//n除尽这个因数
cnt++;
n /= i;
flag = 1;
}
if (flag)
{
x *= i;//记录所有不同的质因数的乘积
a[++tot] = make_pair(cnt, i);//记录底数和指数
}
if (n == 1)
return;
}
if (n > 1)
{//还有大于sqrt(n)的因数
a[++tot] = make_pair(1, n);
x *= n;
}
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
x = 1;
int n;
cin >> n;
tot = 0;
cal(n);
sort(a + 1, a + 1 + tot);//按指数从小到大排序
int ans = 0;//记录答案
int mi = 0;//记录当前已选择的指数
for (int i = 1; i <= tot; i++)
{
ans += x * (a[i].first - mi);
mi = a[i].first;//更新选择的指数
x /= a[i].second;//所有数的乘积减小
if (x == 1)
break;
}
cout << ans << endl;
}
return 0;
}