欧拉函数模板及拓展

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

欧拉公式的延伸:对于一个数,与其互质的数的总和是euler(n)*n/2。
如φ(15)=8,有互质数 1,2,4,7,8,11,13,14,加和后结果为60,而8*15/2结果同为60。
通常用phi表示欧拉函数或存储欧拉函数的数组

特性 :
1.若a为质数,phi[a]=a-1;
2.若a为质数,b mod a=0,phi[a * b]=phi[b] * a【 b是 质数a 的倍数则a*b的欧拉函数是b的欧拉函数的a倍 φ(a * b)=φ(b) * a】
3.若a,b互质,phi[a * b]=phi[a] * phi[b]【当a为质数时,if (b mod a)!=0 ,phi[a*b]=phi[a] * phi[b]】
4.特殊性质:当n为奇数时,φ(2*n)=φ(n)

*φ(1) = 1
*φ(2) = 1
*φ(3) = 2
*φ(4) = 2
φ(5) = 4
*φ(6) = 2
φ(7) = 6
φ(8) = 4
φ(9) = 6
φ(10) = 4
φ(11) = 10
φ(12) = 4
φ(13) = 12
φ(14) = 6
φ(15) = 8
φ(16) = 8
φ(17) = 16
φ(18) = 6
φ(19) = 18
φ(20) = 8
φ(21) = 12
φ(22) = 10
φ(23) = 22
φ(24) = 8
φ(25) = 20
φ(26) = 12
φ(27) = 18
φ(28) = 12
φ(29) = 28
φ(30) = 8
φ(31) = 30
φ(32) = 16
φ(33) = 20
φ(34) = 16
φ(35) = 24
φ(36) = 12
φ(37) = 36
φ(38) = 18
φ(39) = 24
φ(40) = 16
φ(41) = 40
φ(42) = 12
φ(43) = 42
φ(44) = 20
φ(45) = 24
φ(46) = 22
φ(47) = 46
φ(48) = 16
φ(49) = 42
φ(50) = 20

可以发现只有φ(1),φ(2),φ(3),φ(4),φ(6)是质数,其余所有欧拉函数都是合数。

Euler函数表达通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数,x是不为0的整数。

单个数字求解欧拉函数模板:

int phi(int n)
{
    int ans=n,tmp=n;
    for(int i=2; i*i<=tmp; i++)     ///遍历所有质因子,其中tmp遍历范围因为去除了质因子的倍数一直在变小
    {
        if(tmp%i==0)
        {
            ans=ans/i*(i-1);        ///此处是x*(1-1/p1)=x*(p1-1)/p1,为防止溢出,先计算除法
            while(tmp%i==0)tmp/=i;  ///去除质因子倍数
        }
    }
    if(tmp>1)ans=ans/tmp*(tmp-1);
    return ans;
}

线性筛打表欧拉函数:

const int MAXN=100005;
int euler[MAXN];
void Init()
{
    euler[1]=1;
    for(int i=2;i<MAXN;i++) euler[i]=i;
    for(int i=2;i<MAXN;i++)
    {
        if(euler[i]==i)
        {
            for(int j=i;j<MAXN;j+=i)
            {
                euler[j]=euler[j]/i*(i-1);
            }
        }
    }
    for(int i=1;i<=50;i++)printf("φ(%d) = %d\n",i,euler[i]);
}

猜你喜欢

转载自blog.csdn.net/kuronekonano/article/details/81298646
今日推荐