(数论)51NOD 1136 欧拉函数

对正整数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 }

猜你喜欢

转载自www.cnblogs.com/Ekalos-blog/p/9748913.html