定义
~
中与
互质的数的个数叫欧拉函数,记为
对
分解质因数
则有
证明
首先显然
~
中与
互质的数就是
中不与
含有相同质因子的数
那么先简单分析
只有两个质因子的情况
假设
为
的质因子
那么
~
中p的倍数有
个,q的倍数有
个
我们自然要筛掉这些数
但是注意到这里面
的倍数被减了两次
根据容斥原理,当然还要加回来
得
对这个式子稍作变换
只有两个质因数的情况证毕
到这里再用数学归纳法就可以拓展出上述得式子了
实现
根据上述函数定义式
可以得到一个在分解质因数时同时求解单个欧拉函数的方法
时间复杂度为
int phi(int n)
{
int ans=n;
for(int i=2;i<=sqrt(n);++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;
}
当然我们还可以有递推打表的计算
类似埃式筛法
每枚举到一个质数,就更新他的所有倍数的phi值
复杂度约为
void euler(int n)
{
for(int i=2;i<=n;++i) phi[i]=i;
for(int i=2;i<=n;++i)
{
if(phi[i]==i)//发现一个质数
for(int j=i;j<=n;j+=i)//处理("筛")他的倍数
phi[j]=phi[j]/i*(i-1);
}
}
既然有类似埃式筛的递推方法
那么自然也不会少了线性筛
利用线性筛递推求解phi需要用到欧拉函数的两个性质
1.若有
,且满足
,则
2.若有
,且一定不满足
,则
这两条性质会在接下来给出证明
线性筛中每个合数n只会被他的最小质因子p筛一次
于是我们利用这点从
递推到
复杂度为
void euler(int n)
{
memset(mi,0,sizeof(mi));//保存最小质因子
for(int i=2;i<=n;++i)
{
if(mi[i]==0)
{
mi[i]=i; prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;++j)
{
if(mi[i]<prime[j]||prime[j]*i>n)break;
//在线性筛的基础上,加入i是否有比prime[j]更小的质因子的判断
mi[i*prime[j]]=prime[j];//更新最小质因子
if(i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
else phi[i*prime[j]]=phi[i]*prime[j];
//利用上述性质更新
}
}
}
欧拉函数的性质
1. , ~ 中与 互质的数的和为
证明
若有
且
根据更相减损术有
即
~
中与
互质的数是成对出现的,对称轴就是
也就是说
~
中与
互质的数的平均值是
而总和就是
证毕
2.(1)当
互质时,有
(2)对
分解质因数
,则有
证明
这里的两条性质其实是直接应用了积性函数的性质
什么是积性函数
如果当
互质时,有
,则
上述(1)是直接应用了定义
而(2)中将N分解质因数,显然分解的每一项都两两互质
根据积性函数定义也不难得出上述式子
3.(1)若有
,且满足
,则
(2)若有
,且一定不满足
,则
证明
上述(1)中”若有
,且满足
”
说明N和N/p含有相同质因子
我们分析只含有两个质因子p和q的简单情况
二者相除商为p
用数学归纳法扩展出k个质因子的情况可以得到相同结果
上述(2)中 “若有
,且一定不满足
”
说明
和
一定互质
根据积性函数定义有
因为p为素数,所以
得
证毕
4.
证明
设
若有n,m互质,那么
可得
为积性函数
对于n的某个质因子
由上述3.(1)知该式为一个等比数列+1,公比为p
更具等比数列求和公式得
所以
证毕
5.欧拉定理及其推论
若正整数
互质,则有
若正整数
互质,则对于任意正整数b,有