/*
答案:7587456
耗时:0.671572秒
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 12000;//欲求的范围
const int M = 24000;//计算的范围
int k[N + 1];//记录要求的结果
int fp[M];//fp[i]记录i的最小素因数
int pc[M];//记录i的素因数个数
/*
对x进行分解为nc个因数的乘积
int nc 分解的因数个数
int x 要被分解的数
int nS 前面已经分解的因数和
vector<int> &v 记录整个分解的因数之和
*/
void dfs(int nc, int x, int nS, vector<int> &v)//递归计算分解
{
if (nc == 1)//分解结束
{
v.push_back(nS + x);
return;
}
if (fp[x] == x)//x是素数无法分解
return;
for (int i = fp[x]; i <= (int)sqrt((double)x); ++i)//枚举x的可能因数
{
if (x%i == 0)
dfs(nc - 1, x / i, nS + i, v);//继续下去
}
}
int main(void)
{
memset(k, -1, sizeof(k));//将k都预置为-1
//应用筛法求每个数的最小素数数
for (int i = 1; i < M; ++i)
fp[i] = i;
for (int i = 2; i <= (int)sqrt((double)M); ++i)
{
if (fp[i] < i)
continue;
for (int j = i*i; j < M; j += i)
fp[j] = min(fp[j], i);
}
//计算每个数的素因数个数
for (int i = 2; i < M; ++i)
{
int x = i;
while (x > 1)
{
int y = fp[x];
x /= y;
++pc[i];
}
}
//计算k
for (int i = 4; i < M; ++i)
{
if (fp[i] == i)//素数肯定不是和积数
continue;
for (int j = 2; j <= pc[i]; ++j)
{
vector<int> v;
dfs(j, i, 0, v);//对i进行长度为j的因数分解
for (auto itr = v.begin(); itr != v.end(); ++itr)//对不同的分解计算k
{
int u = i - *itr;//计算积与和的差,补上上这些1就成了和积数
if (u >= 0 && u <= N)
{
u += j;//加上分解的长度
if (k[u] < 0)
k[u] = i;
else
k[u] = min(k[u], i);
}
}
}
}
//排序和去重
sort(k, k + N + 1);
auto itr_end = unique(k, k + N + 1);
//求和
long long nSum = 0;
for (auto itr = k; itr != itr_end; ++itr)
nSum += *itr;
cout << nSum << endl;
return 0;
}
|