zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    A % B Problem
    封锁阳光大学
    数楼梯
    海滩防御
    修复公路
    四子连棋
    口袋的天空
    兔子数
    逆序对&求逆序对
    【模板】单源最短路径*
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5806336.html
Copyright © 2011-2022 走看看