欧拉函数 ϕ(x)
ϕ(x)
表示不超过正整数x的数中与x互质的数的个数。
引理1
1.如果p为素数
ϕ(p)=p−1
2.如果n为素数p的x次方
ϕ(n)=ϕ(pa)=(p−1)∗pa−1
2.如果n=i*p,p为素数,且i%p==0
ϕ(n)=p∗ϕ(i)
2.如果n=i*p,p为素数,且i%p!=0
ϕ(n)=(p−1)∗ϕ(i)
3.如果n为素数a与素数b的乘积
ϕ(n)=ϕ(a∗b)=ϕ(a)∗ϕ(b)
引理2
n拆分乘
pa11∗pa21∗pa31∗pa41∗.....∗pakk
的素数幂乘积的表达式
ϕ(n)=n∗(1−1p1)∗(1−1p2)∗(1−1p3)∗......∗(1−1pk)
线性筛欧拉
因为上面的引理1,我们可以在筛素数的同时筛出欧拉。
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1e6+5;
bool su[MAXN];
int sn[MAXN],num,n,t;
int phi[MAXN];
void Get_phi()
{
su[0]=1;su[1]=1;phi[1]=1;
for(int i=2;i<=MAXN;i++)
{
if(!su[i]) sn[++num]=i,phi[i]=i-1;
for(int j=1;sn[j]*i<=MAXN&&j<=num;j++)
{
su[i*sn[j]]=1;
if(!(i%sn[j]))
{
phi[i*sn[j]]=phi[i]*sn[j];
break;
}
phi[i*sn[j]]=phi[i]*(sn[j]-1);
}
}
}
int main()
{
Get_phi();
return 0;
}
O(sqrt(n))求n的欧拉
int getphi(int n)
{
int ret=n;
for(int i=2;i*i<=n;++i)
{
if(n%i) continue;
ret=ret/i*(i-1);
while(n%i==0) n/=i;
}
if(n!=1) ret=ret/n*(n-1);
return ret;
}
欧拉定理
如果a与m互质,则
aϕ(m)≡1(modb)