UVa10791

/*UVa10791 - Minimum Sum LCM
---不难发现,最优情况就是将该数素因子分解
---需要注意几点:
    1)n==1时应该输出2
	2)当只有一个素因子或者没有除本身以外的素数因子时,答案等于本身+1
*/
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<fstream>
#include<string.h>
using namespace std;
typedef long long LL;
const int maxn = 46340+50;
const int M = 4796;   //小于maxn的素数个数

//线性复杂度的Euler素数筛法
bool vis[maxn];
int prime[M];
int Euler(int n){
	memset(vis, 0, sizeof(vis));
	int phi = 0;
	for (int i = 2; i <= n; i++){
		if (!vis[i]) prime[phi++] = i;  //i是素数
		for (int j = 0; j < phi&&i*prime[j] <= n; j++){
			vis[i*prime[j]] = 1;   //筛去
			if (i%prime[j] == 0)break;  //i是合数(当前是合法的),并且这个数已经被筛过
		}
	}
	return phi; //返回素数个数
}
int main(){
	int cnt, iCase = 1, i, n, k,r;
	int m = Euler(maxn);
	/*ifstream fin("a.txt");
	ofstream fout("b.txt");
	while (){
	while (fin>>n&&n){*/
	while (scanf("%d", &n) && n){
		cnt = 0;  //记录因子个数
		k = n;
		LL ans = 0;
		for (i = 0; i < m; i++){
			if (k%prime[i] == 0)cnt++;
			r = 1;
			while (k%prime[i] == 0){ k /= prime[i]; r *= prime[i]; }
			if (r>1)ans += r;
			if (k == 1)break;
		}
		//cnt==0说明该数是一个超过素数表的大素数
		if (cnt == 0)ans = LL(n) + 1;   //是一个大素数
		else if (cnt == 1 && k == 1)ans = LL(n + 1); //说明只有一个因子,k==1保准n已经除尽
		else if (k > 1)ans = ans + k;   //说明n还没有除尽,k是n的一个大素数因子
		printf("Case %d: %lld
", iCase++,ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/td15980891505/p/5806336.html