欧拉函数

http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11550&courseid=0

欧拉函数

Time Limit: 3000ms, Special Time Limit:6000ms, Memory Limit:65536KB
Total submit users: 76, Accepted users: 63
Problem 11550 : No special judgement
Problem description
  一个数x的欧拉函数Φ(x)定义为所有小于x的正整数中与x互质的数的数目,如小于5且和5互质的数有1、2、3、4,一共4个,故Φ(5)=4。

对于任意正整数x,我们定义两种操作: 
1、f(x) = x + Φ(x);
2、g(x) = x * Φ(x);

现在,给定一个数a,问从1开始,需要多少步操作能得到a。
(如,当a = 2时,f(1)即为所求,故答案为1,而当a = 3时,f(f(1))即为所求,故答案为2) 

Input
  每行输入一个整数a(0<a<=100000)。 

Output
  输出需要的步数,如果无法得到,输出-1;

Sample Input
2
3
Sample Output
1
2
#include<iostream>
#include<cstdio>
#include<cstring>
#define Max 100001
using namespace std;
//打欧拉函数表
long long  euler[Max],dp[Max],prime[Max];
void init()
{
    int i,j;
    prime[0]=prime[1]=0;
    for(i=2; i<Max; i++)
        prime[i]=1;
    for(i=2; i*i<Max ;i++)
    {
        if(prime[i])
        {
            for(j=i*i; j<=Max; j+=i)
            {
                prime[j]=0;
            }
        }
    } //这段求出了N内的所有素数

    for(i=1; i<Max; i++)
    {
        dp[i]=Max;
       euler[i]=i;
    }
    for(i=2; i<Max; i++)
    {
        if(prime[i])
        {
            for(j=i; j<Max; j+=i)
            {
               euler[j]=euler[j]/i*(i-1); //此处注意先/fi再*(i-1),否则范围较大时会溢出
            }
        }
    }
}

int main()
{
    init();

    int i;
dp[1]=0;
    for(i=1;i<Max;i++)
    {
        if(i+ euler[i]<Max&&dp[i+ euler[i]]>dp[i]+1)
                dp[i+ euler[i]]=dp[i]+1;
        if(i* euler[i]<Max&&dp[i* euler[i]]>dp[i]+1)
                dp[i* euler[i]]=dp[i]+1;
    }
      long long  n;
    while(scanf("%lld",&n)!=-1)
    {
        if(dp[n]<Max)
            printf("%lld
",dp[n]);
        else
            printf("-1
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cancangood/p/4566438.html