首页 > 其他 > 详细

欧拉函数【学习笔记】

时间:2018-10-06 13:00:43      阅读:518      评论:0      收藏:0      [点我收藏+]

一、引文

1.欧拉函数:指不超过n且与n互素的正整数的个数,其中,n是一个正整数。


 

二、相关知识

1.算数函数:定义在所有正整数上的函数称为算数函数。

2.乘性函数(积性函数):对算数函数? 如果满足对任意两个互素的正整数nm,均有?(nm)=?(n)?(m)

3.完全乘性函数(完全积性函数):对任意的两个正整数nm,均有?(nm)=?(n)?(m)


 

三、性质

1.如果p是素数,那么φ(p)=p-1;反之,如果p是一个正整数且满足φ(p)=p-1,那么p是素数。

2.如果p是素数,a是一个正整数,那么φ(pa)=pa-pa-1.

  证明:pa不互质的有p×1,p×2,…,p×(pa-1-1),p×pa-1 共pa-1个,那么与它互质的就刚好有pa-pa-1。得证。

3.欧拉函数是积性函数,但不是完全积性函数。

4.推论:当n为奇数时,φ(2n)=φ(n)

  证明:由3可知欧拉函数是积性函数,所以φ(2n)=φ(2)φ(n)=φ(n),得证。

5.设n=(p1)a1(p2)a2 (pk)ak为正整数n的素数幂分解,那么

φ(n)=n?(1-1/p1)?(1-1/p2)??(1-1/pk)

  有了上面的一些性质,这些证明都比较易证。一般也通过此公式来求解欧拉函数的值。

6.若gcd(n,i) = 1, 那么gcd(n, n-i)=1.

  证明:(反证法)先假设gcd(nn-i)=kk!=1,那么n%k=0, (n-i)%k=0,可以推出 n = x*k, n-i = y*k,再往下推一步 i = (x-y)*k,这就与gcd(n,i)=1矛盾了。得证。

7.设n是一个大于2的正整数,那么φ(n)是偶数。

8.设n为一个正整数,那么

技术分享图片???????

  证明:假设左边=F(n),先证明F(n)是积性函数,直接把F(m)F(n)用上式左边代入后展开,可以看到最后的展开式就是m*n的各个因子的欧拉函数值相加,所以得到F(n)是积性函数。再根据

技术分享图片

  展开

 技术分享图片

  根据上述性质2

 技术分享图片

  推出

技术分享图片

  得证。

9.欧拉定理:对任何两个互质的正整数a,m(m≥2),有aφ(m)≡1(mod m).


四、代码实现

1.纯粹且不优雅的无脑实现

 兄台,你还能再暴力一点吗!

int phi(int n)
{
    int rea = n;
    for(int i = 2; i <= n; i++)
    {
        if(n%i == 0)    //找到了素因子
        {
            rea = rea - rea/i;   //rea*(1-1/i)
            do
            {
                n/=i;
            }
            while(n%i==0);
        }
    }
    return rea;
}

  

 2.线性筛素数表实现

我只想说,我TM之前学的筛素数都是假的!

const int MAXN = 1e5;
bool isPrime[MAXN];
int Prime[MAXN], Cnt;

void getPrime()
{
    memset(isPrime, 0, sizeof(isPrime));
    Cnt = 0;
    for(int i = 2; i < MAXN; i++)
    {
        if(!isPrime[i])
        {
            Prime[Cnt++] = i;
        }
        for(int j = 0; j < Cnt && i*Prime[j] < MAXN; j++)
        {
            isPrime[j*Prime[j]] = 1;
            if(i%Prime[j] == 0)
                break;
        }
    }
}

int phi(int n)
{
    int rea = n;
    for(int i = 0; Prime[i]*Prime[i] <= n; i++)
    {
        if(n%Prime[i] == 0)
        {
            rea = rea - rea/Prime[i];  //rea = rea*(1-1/p)
            do
            {
                n/=Prime[i];
            }while(n%Prime[i] == 0);
        }
    }
    if(n > 1)
        rea = rea - rea/n;
    return rea;
}

  

3.递推求欧拉函数

如果频繁的要用欧拉函数值,就需要先打表。

咦~~,我们好像在哪见过,和埃式筛素数怎么这么像呢~

可以先预先置所有欧拉函数值都为本身。如果再从小到大遍历的过程中,发现该欧拉函数的值与下标相当,就表明该数是素数,然后再通过欧拉函数的求法,乘以(1-1/p)。然后再把有该素因子的数的欧拉函数的值再修改一下,就可以了。复杂度为O(n*ln(n))

 

const int MAXN = 1e5;
int Phi[MAXN];

int Euler()
{
    for(int i = 1; i < MAXN; i++)  Phi[i] = i;
    for(int i = 2; i < MAXN; i+=2)  Phi[i]/=2;
    for(int i = 3; i < MAXN; i+=2)
    {
        if(Phi[i] == i) //i是素数
        {
            for(int j = i; j < MAXN; j+=i)
            {
                Phi[j] = Phi[j]/i*(i-1);     // x*(1-1/i) Phi[j]有素因子i
            }
        }
    }
}

  

 


 五、扩展学习

下面是学习的另外一篇博主的博客,他写的比我好,我把他没证的一点内容证了,在此感谢这位博主。

https://www.cnblogs.com/linyujun/p/5194170.html

另一种,比上面更快的方法

 

需要用到如下性质

 

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 )   (我不会证明)

 

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

第一个证明如下,第二个证明原理相同,只不过i没有素因子p。

技术分享图片

欧拉函数是积性函数,能分开的前提是gcd(a,b)=1

技术分享图片

技术分享图片

技术分享图片

素数次幂的欧拉函数值反向运用

技术分享图片

技术分享图片

得证。

const int MAXN = 1e6;
int Prime[MAXN], Phi[MAXN];
int tot;    //记录素数个数

void Euler()
{
    memset(Phi, 0, sizeof(Phi));
    Phi[1] = 1;
    tot = 0;
    for(int i = 2; i < MAXN; i++)
    {
        if(!Phi[i]) //i为素数
        {
            Prime[tot++] = i;
            Phi[i] = i - 1;
        }
        for(int j = 0; j < tot && (long long)Prime[j]*i < MAXN; j++)
        {
            if(i%Prime[j])
            {
                Phi[ i*Prime[j] ] =  Phi[i]*(Prime[j] - 1);
            }
            else    //  Prime[j]是i的素因子
            {
                Phi[ i*Prime[j] ] = Phi[i]*Prime[j];
                break;
            }
        }
    }
}

  

  

还有以下几个实用的公式

假设a与p互质

技术分享图片

因为

技术分享图片

所以

技术分享图片

如果p是素数

技术分享图片

这个公式的意义在于在求指数幂的时候,如果b非常大,我们可以不用死求a^b的快速幂,可以先对b取模再求。


 

 

欧拉函数【学习笔记】

原文:https://www.cnblogs.com/dybala21/p/9744440.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!