对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。例如:φ(8) = 4(Phi(8) = 4),因为1,3,5,7均和8互质。
Input
输入一个数N。(2 <= N <= 10^9)
Output
输出Phi(n)。
Input示例
8
Output示例
4
解:简单说明一下基本情况,复杂情况可类推。若n=a^p*b^q(a,b为质数或1),则phi(n)=n-n/a-n/b+n/(a*b)=n*(1-1/a-1/b+1/(a*b))=n*(1-1/a)*(1-1/b)=n*(a-1)*(b-1)/(a*b);
所以我们可以得到如下公式phi(n)=n*(a-1)*(b-1)*(c-1).../(a*b*c...)=(n/(a*b*c...))*(a-1)*(b-1)*(c-1)...(避免大数相乘爆int);
1 #include <stdio.h> 2 #include <math.h> 3 4 #define CLR(x) memset(x,0,sizeof x) 5 6 int num[30]; 7 8 void deco(int a) 9 { 10 int j = 0; 11 for (int i = 2; i <= sqrt((double)a) && a != 1; i++) 12 { 13 if (0 == a%i) 14 { 15 num[j++] = i; 16 do a /= i; 17 while (a%i == 0); 18 } 19 } 20 if (a != 1) num[j++] = a; 21 return ; 22 } 23 24 int main() 25 { 26 int n; 27 while (scanf_s("%d", &n) != EOF) 28 { 29 int temp = 1, mult = 1; 30 CLR(num); 31 deco(n); 32 for (int i = 0; num[i]; i++) 33 { 34 temp *= (num[i] - 1); 35 mult *= num[i]; 36 } 37 printf("%d\n", n / mult * temp); 38 } 39 }
改进一下,写成函数
1 #include <stdio.h> 2 3 int phi(int n) 4 { 5 int ans = n; 6 for (int i = 2; i * i <= n && n != 1; i++) 7 { 8 if (0 == n%i) 9 { 10 ans = ans / i * (i - 1); 11 do n /= i; 12 while (n % i == 0); 13 } 14 } 15 if (n != 1) ans = ans / n * (n - 1); 16 return ans; 17 } 18 19 int main() 20 { 21 int n; 22 while (scanf_s("%d", &n) != EOF) printf("%d\n", phi(n)); 23 return 0; 24 }