欧拉函数的定义:
对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)。此函数以其首名研究者欧拉命名(Euler's totient function),它又称为Euler's totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质。 从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明。
注:
互质的定义:摘自百科
若N个整数的最大公因数是1,则称这N个整数互质。
例如8,10的最大公因数是2,不是1,因此不是整数互质。
7,11,13的最大公因数是1,因此这是整数互质。
5和5不互质,因为5和5的公因数有1、5。
1和任何数都成倍数关系,但和任何数都互质。因为1的因数只有1,而互质数的原则是:只要两数的公因数只有1时,就说两数是互质数。因为1只有一个因数所以1既不是质数(素数),也不是合数,无法再找到1和其他数的别的公因数了。1和-1与所有整数互素,而且它们是唯一与0互素的整数。
方法一:
根据定义判断来写
int Euler(int n)
{
int cnt=0;
for(int i=0;i<=n;i++)
{
if(gcd(i,n)==1) cnt++;
}
return cnt;
}
方法二:
,
,
,...,
是P的质因数
则φ(P)=P*(1-/1)*(1-
/1)*...*(1-
/1)
例如,φ(10) = 10*(1/2)*(4/5)= 4
int Euler(int n)
{
int res=n;
for(int i=2;i<=n;i++)
{
if(n%i==0)
{
res=res/i*(i-1);
}
while(n%i==0)
{
n/=i;
}
}
return res;
}
因为一个数的质因子只可能有一个大于这个数的平方根,这个质因子可以再最后特判。所以可以这样优化:
int Euler(int n)
{
int res=n;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
res=res/i*(i-1);
}
while(n%i==0)
{
n/=i;
}
}
if(n>1) res=res/n*(n-1);//判断是否有一个大于根号下n的质因子
return res;
}
方法三: 区间预处理欧拉函数
这样可以获得n以内所有数的欧拉函数值,参考素数筛法,使用的也是方法二的规律
int euler[1000];
int Euler(int n)
{
for(int i=1;i<=n;i++)
{
euler[i]=i;
}
for(int i=2;i<=n;i++)
{
if(euler[i]==i)
{
for(int j=i;j<=n;j+=i)
{
euler[j]=euler[j]/i*(i-1);
}
}
}
}