欧拉函数

定义:给定正整数n,小于等于n的正整数之中,有多少个数与n互质

计算个数的公式 欧拉函数,φ(n)表示

欧拉函数证明:

  1. n = 1, φ(1) = 1 。1与任何数(包括自身)互质

  2. n为质数, φ(n)=n-1 。质数n与小于n的数互质(除了自身)

  3. 如果n是质数的次方 n = p^k ( p 为质数,k 为大于等于1的整数)。

   2015-08-04/55c0573f4a25a

   因为为p(质数)的k次方,则n的因子只有 p 。

   小于(p^k)的数有(p^k - 1)个

   所以p的倍数与n皆有(1,p)两个因子,除了p的倍数,其他数都与n互质

   所以小于n的数中为p的倍数的个数为:(p^k)/p - 1

   所以 φ(n) =  (p^k - 1) - ((p^k)/p - 1)

         =  p^k - p^k)/p

         =  p^k - p^(k-1)

         =  p^k(1 - 1/p)

       

  4. n = p * q (p, q互质)

    φ(n) = φ(p*p) = φ(p)*φ(q)

  5. 任意大于1的n

    n可以写成多个质数次方的积

            2015-08-04/55c057f99f735

    2015-08-04/55c05835ca6e2

    2015-08-04/55c05871f2594

    2015-08-04/55c058b16129e

直接求n的欧拉函数φ(n)

ll Euler(ll n)
{
    ll ans = 1;
    ans = ans * n;
    for(ll i = ; i * i <= n; i++)
    {
        if(n % i == 0) ans = ans / i * (i - 1);
        while(n % i == 0) n /= i;
    }
    if(n > 1) ans = ans / n * (n - 1);
    return ans;

}
View Code

 欧拉函数线性筛法证明:

性质:H(x * p) = H( x ) * (p - 1) / p

以下p均为素数情况下求取欧拉函数(所以线性筛法与素数筛法结合)

1.  phi( p ) = p - 1

2.  phi( p ^ k ) = p ^ k * (1 - 1 / p) = (p - 1) * p ^ (k - 1)

3.  if( i % p == 0), phi( i * p ) = p * phi( i );

  φ( i ) = i * (1-1/p1) * (1 - 1/p2)...(1 - 1/pr)

  因为 i 是 p 的倍数,且p为素数

  φ( i * p ) = i * p * (1-1/p1) * (1 - 1/p2)...(1 - 1/pr)

          = p * i * (1-1/p1) * (1 - 1/p2)...(1 - 1/pr)

       = p * φ( i ) 

4.  if(  i % p != 0), phi( i * p ) = ( p - 1 ) * phi( i );

  φ( i ) = i * (1-1/p1) * (1 - 1/p2)...(1 - 1/pr)

  因为 i 不是 p 的倍数,且p为素数,所以

  φ( i * p ) = i * p * (1-1/p1) * (1 - 1/p2)...(1 - 1/pr) * (1 - 1/p)

           =  i * (1-1/p1) * (1 - 1/p2)...(1 - 1/pr) * (p - 1)

        = (p - 1) * φ( i ) 

 欧拉函数φ(n)的线性筛法,求1 - n 中的欧拉值

 1 const int maxn = 1e8;
 2 int phi[maxn], prime[maxn], vis[maxn];
 3 int n, cnt = 0;
 4 void getphi(int n)
 5 {
 6     memset(vis, 0, sizeof(vis));
 7     phi[1] = 1;
 8     for(int i = 2; i <= n; i++)
 9     {
10         if(!vis[i]) //i是素数
11         {
12             prime[++cnt] = i;
13             phi[i] = i - 1;
14         }
15         for(int j = 1; j <= cnt; j++)
16         {
17             if(i * prime[j] > n)
18                 break;
19             vis[i*prime[j]]= 1;
20             if(i % prime[j] == 0)
21             {
22                 phi[i*prime[j]] = prime[j] * phi[i];
23                 break;
24             }
25             else
26             {
27                 phi[i*prime[j]] = (prime[j]-1) * phi[i];
28             }
29 
30         }
31     }
32 }
View Code

 

posted @ 2019-04-11 21:42  窗子外和窗子里  阅读(458)  评论(0编辑  收藏  举报