本来是采用暴力的,后来搜索了一下才知道原来用欧拉函数,于是去搜索了欧拉函数,讲得很详细~不过函数的证明倒是没有推导。。。
首先,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; }