欧拉函数定义:对于正整数N,小于或等于N 且 与N互质的正整数的个数,记为phi(N);
phi(N) = N * (1-1/p1) * (1-1/p2) * (1-1/p3) * ...... * (1-1/pk)
这里的p1、p2 ...... pk 是 N 所有的质因数。
欧拉函数性质(推导):
1、phi(1) = 1;
2、若N为素数,则phi(N) = N-1;
3、若N为奇数,则phi(2N ) = phi(N);
4、欧拉定理:对任意两个互质的正整数a、n(n>2) 有同余方程:a^phi(n) = 1 (mod n)
5、费马小定理:当a与n互质,且n为素数时有同余方程:a^(n-1) = 1 (mod n)
下面给出计算单个欧拉函数phi(n)的值的代码:
1 // 计算单个欧拉函数phi(n)的值 2 int enler_phi(int n){ 3 int m = (int)sqrt(n+0.5); // 避免浮点误差 4 int ans = n; 5 for(int i = 2; i <= m; ++i) if(n % i == 0) { 6 ans = ans/i * (i-1); 7 while(n % i == 0) n /= i; 8 } 9 //为了减少时间复杂度,我们先对n开根号得到m,再从2遍历到m, 10 //这样我们只得到了将n分解之后小于等于m的质因子,n分解之后 11 //可能会存在一个(且只有一个)大于m的质因子,其中的道理不 12 //难明白 13 if(n > 1) ans = ans / n * (n-1); 14 return ans; 15 }
我们还可以借鉴筛法的方法计算phi(1)、phi(2)、phi(3)、.......、phi(n)
1 int phi[maxn]; 2 void enler_phi(int n){ 3 memset(phi, 0, sizeof(phi)); 4 phi[1] = 1; 5 for(int i = 2; i <= n; ++i) if(!phi[i]) 6 for(int j = i; j <= n; j += i){ 7 if(!phi[j]) phi[j] = j; 8 phi[j] = phi[j] / i * (i-1); 9 } 10 }
欧拉函数可以试试这题:https://vjudge.net/problem/HDU-1286