数论之旅4---欧拉函数的证明及代码实现(我会证明都是骗人的╮( ̄▽ ̄)╭)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论之旅4---欧拉函数的证明及代码实现(我会证明都是骗人的╮( ̄▽ ̄)╭)相关的知识,希望对你有一定的参考价值。

欧拉函数,用φ(n)表示

欧拉函数是求小于n的数中与n互质的数的数目

 

 

 

辣么,怎么求哩?~(~o ̄▽ ̄)~o

 

可以先在1到n-1中找到与n不互质的数,然后把他们减掉

 

比如φ(12)

把12质因数分解,12=2*2*3,其实就是得到了2和3两个质因数

然后把2的倍数和3的倍数都删掉

2的倍数:2,4,6,8,10,12

3的倍数:3,6,9,12

 

本来想直接用12 - 12/2 - 12/3

但是6和12重复减了

所以还要把即是2的倍数又是3的倍数的数加回来 (>﹏<)

所以这样写12 - 12/2 - 12/3 + 12/(2*3)

这叫什么,这叫容斥啊,容斥定理听过吧

比如φ(30),30 = 2*3*5

所以φ(30) = 30 - 30/2 - 30/3 - 30/5 + 30/(2*3) + 30/(2*5) + 30/(3*5) - 30/(2*3*5)

 

但是容斥写起来好麻烦( ̄. ̄)

有一种简单的方法

φ(12)   =   12*(1 - 1/2)*(1 - 1/3)                 =   12*(1 - 1/2 - 1/3 + 1/6)

φ(30)   =   30*(1 - 1/2)*(1 - 1/3)*(1 - 1/5)   =   30*(1 - 1/2 - 1/3 - 1/5 + 1/6 + 1/10 + 1/15 - 1/30)

你看( •?∀•? ),拆开后发现它帮你自动帮你容斥好

 

所以φ(30)的计算方法就是先找30的质因数

分别是2,3,5

然后用30* 1/2 * 2/3 * 4/5就搞定了

 

代码如下:

 1 //欧拉函数
 2 int phi(int x){
 3     int ans = x;
 4     for(int i = 2; i*i <= x; i++)
 5         if(x % i == 0){
 6             ans = ans / i * (i-1);
 7             while(x % i == 0) x /= i;
 8         }
 9     if(x > 1) ans = ans / x * (x-1);
10     return ans;
11 }

 

(phi就是φ的读音)

 

 

机智的代码,机智的我(??`ω´?)

 

 

这个的复杂度是O(√n),如果要你求n个数的欧拉函数,复杂度是O(n√n),这也太慢了

 

有更快的方法,线筛欧拉函数

需要用到如下性质

p为质数

1. phi(p)=p-1   因为质数p除了1以外的因数只有p,故1至p的整数只有p与p不互质 

2. 如果i mod p = 0, 那么 phi(i * p)=phi(i) * p         (我不会证明)

3.若i mod p ≠0,  那么 phi( i * p )=phi(i) * ( p-1 )   (我不会证明)

(所以我说我会证明都是骗人的╮( ̄▽ ̄)╭)

 

代码如下:

 1 #include<cstdio>
 2 using namespace std;
 3 const int M = 1e6+10 ;
 4 int phi[M] , prime[M];
 5 int tot;//tot计数,表示prime[M]中有多少质数 
 6 int Euler () {
 7     for (int i = 2 ; i < M ; i ++) {
 8         if (!phi[i]) {
 9             phi[i] = i-1 ;
10             prime[ ++tot ] = i ;
11         }
12         for (int j = 1 ; j <= tot && 1ll*i*prime[j] < M ; j ++) {
13             if (i % prime[j]) phi[i * prime[j]] = phi[i] * (prime[j]-1) ;
14             else {
15                 phi[i * prime[j] ] = phi[i] * prime[j] ;
16                 break ;
17             }
18         }
19     }
20 }
21  
22 int main () {
23     Euler () ;
24 }

(Euler就是欧拉)

 

 

机智的代码,机智的我(??`ω´?)

 

 

 

 

 

 

 

以上是关于数论之旅4---欧拉函数的证明及代码实现(我会证明都是骗人的╮( ̄▽ ̄)╭)的主要内容,如果未能解决你的问题,请参考以下文章

数学数论初探欧拉定理

欧拉定理及扩展

NOIP训练规律+数论欧拉函数的应用

各种友(e)善(xin)数论总集(未完待续),从入门到绝望

《夜深人静写算法》数论篇 - (17) 扩展欧拉定理

数论——欧拉定理