欧拉函数

Posted rgbth

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了欧拉函数相关的知识,希望对你有一定的参考价值。

问:求小于n等于且与n互素的正整数的个数

两个整数互素即:两个数gcd为1

解:

根据唯一分解定理,大于1的整数均可看成若干素数的乘积的形式

若n=1,答案为1;

若n>1;

可以这样考虑:

把n看成若干素数的乘积n=p1^k1*p2^k2*···*pm^km;(p1,p2,···,pm均为素数)(k1,k2,···,km均为非负整数)S1={p1,p2,···,pm}

那么对于满足条件的数s必有s=q1^t1*q2^t2*···*ql^tl;(q1,q2,···,qm均为素数)(t1,t2,···,tm均为非负整数)S2={q1,q2,···,qm}

s1∩S2为空集;

那么即1~n-1中所有素因子不包含S1中的数即符合题意,但是这样做太麻烦了,可以反过来考虑,

把不符合条的数去掉即可,这个可以用容斥原理解决

首先n减掉小于n且为S1中元素倍数的数量

n-n/p1-n/p2-···-n/pk;

再加上小于n且为S1中两个不同元素乘积的的数量

n-n/p1-n/p2-···-n/pm+n/(p1*p2)+n/(p1*p3)+···+n/(p(m-1)*pm);

再减去小于n且为S1中三个不同元素乘积的数量

·······

最终得到φ(n)=Σ(s?{ p1,p2,pm }(-1)^|S|*n/∏(pi∈S)pi;

但是这个公式有2^n次方项,有时不如暴力;

但是我们可以将它变形,φ(n)=n(1-1/p1)(1-1/p2)···(1-1/pm);

将上述公式展开正好符合推导过程;

根据这个我们可以编码实现

euler(int n)
{
int m=(int)sqrt(n+0.5);
int ans=n;
for(int i=2; i<=m; i++)
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
if(n>1)
ans=ans/n*(n-1);
return ans;
}

 求1到n的欧拉函数值,不用一个一个计算,这样考虑,对于1~n中的任意一个素数p,其小于等于n的倍数的欧拉函数都必须乘以(p-1)/p,那么我们对于1~n所有的素数都将其倍数乘以这个值,再遍历完全部素数后,1~n的欧拉函数值都已经计算过了;

编码实现

<span>

void phi_seive(int n){
memset(phi,0,sizeof(phi));
phi[1]=1;
for(int i=2;i<=n;i++)
if(!phi[i]){
for(int j=i;j<=n;j+=i){
if(!phi[j])phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}

</span>
























以上是关于欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章

欧拉函数5等于多少

欧拉函数计算公式是啥?

蓝桥杯必备算法一:欧拉函数

φ函数的欧拉函数的值

欧拉函数性质与求法 [数论][欧拉函数]

数论讨伐!欧拉函数!