欧拉函数的代码实现

一、n的欧拉phi函数值

思路:需要用试除法依次判断√n内的素数,这样需要先生成√n内的素数表,但其实不必这么麻烦:只需要每次找到一个素因数之后把它“除尽”,即可保证找到的因数都是素数(假如当前找到的因素不是素数,则存在更小的因数,与“除尽“矛盾)

O(√n)

 1 int euler_phi(int n)
 2 {
 3     int m = (int)sqrt(n + 0.5);
 4     int ans = n;
 5     for (int i = 2; i <= m; i++)
 6     {
 7         if (n % i == 0)
 8         {
 9             ans = ans / i * (i - 1);
10             while (n % i == 0)  n /= i;        //除尽
11         }
12     }
13     if (n > 1)  ans = ans / n * (n - 1);    //剩下的不为1,也是素数
14     return ans;
15 }

二、1~n中所有数的欧拉phi函数值

思路:与素数筛法非常类似,先筛得素数,然后乘到phi值上(因为如果含有素数p,那么公式中会包含(1 - 1/p))

O(nloglogn)

 时间复杂度与埃氏筛法一样的

 1 const int maxn = 100000 + 10;
 2 int phi[maxn];
 3 void phi_table(int n, int* phi)
 4 {
 5     for (int i = 2; i <= n; i++);
 6     phi[1] = 1;
 7     for (int i = 2; i <= n; i++)
 8     {
 9         if (!phi[i])            //筛法得到素因数i,此时1~i的phi值已经确定
10         {
11             for (int j = i; j <= n; j += i)
12             {
13                 if (!phi[j])  phi[j] = j;
14                 phi[j] = phi[j] / i * (i - 1);  //更新
15             }
16         }
17     }
18 }

 

posted @ 2018-09-09 11:36  Rogn  阅读(896)  评论(0编辑  收藏  举报