欧拉函数

欧拉函数 Euler' totient function

φ(n)表示 1~n 中 且与n互质的数的个数


 

通式:

  φ(n) = n *  ∏质数p | n (1 - 1 / p) ;

  即: n = p1k1 * p2k2 * p3k3 * ...... * pmkm

     φ(n) = n * (1 - 1 / p1) * (1 - 1 / p2) * (1 - 1 / p3) * ...... * (1 - 1 / pm)

特别地 :φ(1) = 1;

    当 n 是质数时  φ(n) = n - 1

    当 n 是奇数时  φ(2n) = φ(n)


 

性质:

    • 欧拉函数是积性函数 :若 gcd(a, b) = 1 ;  则 φ(a * b) = φ(a) * φ(b) ;   特别地 :当 n 为奇数时 φ(2n) = φ(n) ; 

      积性函数:对于任意互质的整数 a 和 b 有性质 ƒ(a * b) =ƒ(a)  * ƒ(b)

      完全积性函数:对于任意整数 a 和 b 有性质 ƒ(a * b) = ƒ(a)  * ƒ(b) ;

  积性函数的性质:

      •  n = p1a1 * p2a2 * p3a3 * ...... * pnan   —— n 表示质因数的分解式 ;
      • 若 ƒ 为积性函数 且 n = p1a1 * p2a2 * p3a3 * ...... * pnan  ,则 ƒ(n) = ƒ(p1a1) * ƒ( p2a2)  * ƒ(p3a3)  * ...... *ƒ(pnan
      • 若 ƒ 为积性函数 且有 ƒ(pn)  = ƒ n(p) ,则 ƒ 为完全积性函数 ;  
      • 特别地 : 当 n 为奇数时 ƒ(2n) = ƒ(n) ; 
    • n = ∑d | n  φ(d)  ,d | n  φ(d) = n
    • 对任意 n > 1 ,1 ~ n 中与 n 互质的数的和为 n * φ(n) / 2
    • n = p k ,其中 p 是质数,那么 φ(n) = p  - p k - 1  =(p - 1) * p k - 1  ;
    • 设 p 为质数,若 p | n 且 p2 | n (p2  是 n 的质数),即:n,n / p 包含相同的质因子

           则: φ(n) = φ(n / p) * p ;(φ(n) =  n *  ∏质数p | n (1 - 1 / p) ; φ(n / p) =  (n / p) *  ∏质数p | n / p (1 - 1 / p) ;  则 φ(n) / φ(n / p)  = p)

    • 设 p 为质数,若 p | n 且 p† n (p不是 n 的质数),即:p,n / p 互质

           则:φ(n) = φ(n / p) * (p - 1) ;(由积性函数 可得 φ(n) = φ(n / p) * φ(p) ;p 是质数 可得 φ(p) = p - 1)


 

模板:

  • 求一个数的欧拉函数

 根据欧拉函数的计算公式:φ(n) = n *  ∏质数p | n (1 - 1 / p) ;只需要分解质因数,即可求出欧拉函数

 1 int phi(int n) {
 2   int ans = n;
 3   for (int i = 2; i * i<= n; i++)
 4     if (n % i == 0) {
 5       ans = ans / i * (i - 1);
 6       while (n % i == 0) n /= i;
 7     }
 8   if (n > 1) ans = ans / n * (n - 1);
 9   return ans;
10 }
View Code
  • 求2~n 中每个数的欧拉函数  
    • 利用埃拉托斯托尼筛法(埃氏筛法的核心是:如果 x 是合数,那么 x 的倍数也是合数;合数与质数相对,最小合数是4,1既不是合数也不是质数)  时间复杂度:O(nlogn)
1 void euler(int n) {
2     for (int i = 2; i <= n; i++) phi[i] = i;
3     for (int i = 2; i <= n; i++)
4         if (phi[i] == i)
5             for (int j = i; j <= n; j += i)
6                 phi[j] = phi[j] / i * (i - 1);
7 }
View Code
    • 利用线性筛法      时间复杂度:O(n)

  由性质:

    1.设 p 为质数,若 p | n 且 p2 | n (p2  是 n 的质数),即:n,n / p 包含相同的质因子,则: φ(n) = φ(n / p) * p ;

    2.设 p 为质数,若 p | n 且 p† n (p2  不是 n 的质数),即:p,n / p 互质,则:φ(n) = φ(n / p) * (p - 1) ;

  在线性筛法中,每个合数 n 只会被它的最小质因子 p 筛一次,可通过上面的两条性质 从 φ(n / p) 递推到 φ(n)

 1 int v[MAX_N], prime[MAX_N], phi[MAX_N];
 2 int m;
 3 void euler(int n) {
 4     memset(v, 0, sizeof(v)); //标记最小质因子
 5     m = 0; //质数数量
 6     for (int i = 2; i <= n; i++) {
 7         if (v[i] == 0) { //i是质数
 8             v[i] = i;
 9             prime[++m] = i; //存储质数
10             phi[i] = i - 1;
11         }
12         //给当前的数i乘上一个质因子
13         for (int j = i; j <= m; j++) {
14             if (prime[j] > v[i] || prime[j] > n / i) //i有比prime[j]更小的质因子,或者超出n的范围,停止循环
15                 break;
16             v[i * prime[j]] = prime[j]; //prime[j]是合数i*prime[j]的最小质因子
17             phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]); //判断使用上面的性质1还是2
18 
19         }
20     }
21 }
View Code

 

posted @ 2021-01-31 18:03  巨大力选手  阅读(602)  评论(0)    收藏  举报