欧拉函数辱骂你 2333333333

来源:互联网 发布:软件产品出口退税政策 编辑:程序博客网 时间:2024/05/10 08:22

有一篇博客写的很大佬,有时间好好研究一下:http://blog.csdn.net/qq_39922639/article/details/77511761

欧拉函数简介:

写在前面:

欧拉函数只是工具:提供1到N中与N互质的数

定义和简单性质

欧拉函数在OI中是个非常重要的东西,不知道的话会吃大亏的.

欧拉函数用希腊字母φ表示,φ(N)表示N的欧拉函数.

对φ(N)的值,我们可以通俗地理解为小于N且与N互质的数的个数(包含1).

欧拉函数的一些性质:

1.对于素数p, φ(p)=p-1,对于对两个素数p,q φ(pq)=pq-1

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

证明:

函数的积性即:若m,n互质,则φ(mn)=φ(m)φ(n).由“m,n互质”可知m,n无公因数,所以φ(m)φ(n)=m(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pn)·n(1-1/p1')(1-1/p2')(1-1/p3')…(1-1/pn'),其中p1,p2,p3...pn为m的质因数,p1',p2',p3'...pn'为n的质因数,而m,n无公因数,所以p1,p2,p3...pn,p1',p2',p3'...pn'互不相同,所以p1,p2,p3...pn,p1',p2',p3'...pn'均为mn的质因数且为mn质因数的全集,所以φ(mn)=mn(1-1/p1)(1-1/p2)(1-1/p3)…(1-1/pn)(1-1/p1')(1-1/p2')(1-1/p3')…(1-1/pn'),所以φ(mn)=φ(m)φ(n).

即φ(mn)=φ(n)*φ(m)只在(n,m)=1时成立.

2.对于一个正整数N的素数幂分解N=P1^q1*P2^q2*...*Pn^qn.

   φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn).

3.除了N=2,φ(N)都是偶数.

4.设N为正整数,∑φ(d)=N (d|N).

根据性质2,我们可以在O(sqrt(n))的时间内求出一个数的欧拉函数值.

如果我们要求1000000以内所有数的欧拉函数,怎么办.

上面的方法复杂度将高达O(N*sqrt(N)).

我们来看看线性筛法的程序:


数论中,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质

——百度百科词条《欧拉函数》

        欧拉函数通式:



    为了方便编程通常不用这个通式,而用Φ(x)=p1^(n1-1)*p2^(n2-1)* ... *pk^(nk-1)*(p1-1)*(p2-1)* ... *(pk-1)计算,其中p1,p2,..pk为正整数x的质因数,n1,n2,...nk对应质因数的次数。

    该式易通过欧拉函数的性质推导出来。首先将正整数n进行质因数分解(小学数学的即视感

    欧拉函数有如下性质,若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为在1至p^k这n个数中除了p的倍数外,其他数都跟n互质。而p的倍数共有n/p即p^k/p^1=p^(k-1)个。

    另外欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。

        所以有:


对一个正整数N,欧拉函数是小于N且与N互质的数的个数.

例如φ(24)=8,因为1, 5, 7, 11, 13, 17, 19, 23均和 24 互质。

φ(n) = n*(1-1/p1)*(1-1/p2)*......(1-1/pn)   其中(p1.....pn)为N的素因子


欧拉函数的基本性质:


① N是不为0的整数。φ(1)=1(唯一和1互质的数就是1本身)

② 除了N=2,φ(N)都是偶数.

③ 小于N且与N互质的所有数的和是φ(n)*n/2

④ 欧拉函数是积性函数——若m,n互质,φ(m*n)=φ(m)*φ(n)。

⑤ 当N为奇数时,φ(2*N)=φ(N)

⑥ 若N是质数p的k次幂,φ(N)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟N互质

⑦ 当N是质数时,φ(N) = N-1

欧拉函数线性筛:
#include<iostream>    #include<cstdio>    #define N 40000    using namespace std;    int n;    int phi[N+10],prime[N+10],tot,ans;    bool mark[N+10];    void getphi()    {       int i,j;       phi[1]=1;       for(i=2;i<=N;i++)//相当于分解质因式的逆过程       {           if(!mark[i])               {                 prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。                 phi[i]=i-1;//当 i 是素数时 phi[i]=i-1                 }           for(j=1;j<=tot;j++)           {              if(i*prime[j]>N)  break;              mark[i*prime[j]]=1;//确定i*prime[j]不是素数              if(i%prime[j]==0)//接着我们会看prime[j]是否是i的约数              {                 phi[i*prime[j]]=phi[i]*prime[j];break;              }              else  phi[i*prime[j]]=phi[i]*(prime[j]-1);//其实这里prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性           }       }    }    int main()    {        getphi();    }    


原创粉丝点击