本来是采用暴力的,后来搜索了一下才知道原来用欧拉函数,于是去搜索了欧拉函数,讲得很详细~不过函数的证明倒是没有推导。。。

首先,prime的初始化,参考了百度百科:

 

void init_prime()
{
    memset(prime,1,sizeof(prime));
    prime[0] = prime[1] = 0;
    for(int i = 2; i * i<= Max; i++)
    {
        if(prime[i])
        {
            for(int j = i * i; j <= Max; j += i)
                prime[j] = 0;
        }
    }
}

之后,φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数(小于等于1)就是1本身)。由这个便可以很轻松地理解如何用编程求解1..N的φ函数:

 

 

for(int i = 1; i <= N; i++)
        phi[i] = i;
    for(int i = 2;i <= N; i++)
        if(prime[i])
            for(int j = i;j <= N; j += i)
                phi[j] = phi[j] / i * (i - 1);//此处注意先/ i 再*(i-1),否则范围较大时会溢出


根据这个例子φ(72)=φ(2^3×3^2)=(2-1)2^(3-1)×(3-1)3^(2-1)=24
不难理解以下程序:(参考了http://www.cnblogs.com/yylogo/archive/2011/06/04/sgu-102.html的程序)

 AC代码:

 

#include<iostream>
using namespace std;
int main()
{
    //如φ(72)=φ(2^3×3^2)=(2-1)2^(3-1)×(3-1)3^(2-1)=24
    int n,x;
    cin>>n;
    x = n;
    for(int i = 2; n != 1; i++)
    {
        if(n % i == 0)
        {
            x = x / i * (i - 1);  //此处可以跟<span style="color: rgb(51, 51, 51); font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; orphans: 2; text-indent: 28px; widows: 2;">φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn)对应</span>
            while(n % i == 0)
            {
                n /= i;
            }//例子中 先遇到2 则不断被2整除,直至不能再除  接着再遇到3,再接着
        }
    }
    cout<<x<<endl;
    return 0;
}