欧拉函数(求与n互质并小于n的数的个数的那个)
欧拉函数phi(x)有3条性质、2条定理:
性质1:如果p是素数,则phi(p)=p-1。这个显然成立。
性质2:如果p是素数,则phi(p^k)=(p-1)*p^(k-1)。
证明:因为p是素数,所以只有p的倍数不与p^k互质,1~p^k之间p的倍数有p、2p...p*p、p*(p+1)...p^k,总共有p^(k-1)个。
所以phi(p^k)=(p^k-1)-(p^(k-1)-1)=(p-1)*p^(k-1)。
性质3:如果p、q均为素数,则phi(p*q)=phi(p)*phi(q)。这个证明起来比较麻烦,今天先不写,有空再补。
有上面3条性质,可以得到下面2条定理:
定理1:如果p是素数,并且p为n的约数,那么phi(n*p)=phi(n)*p。
证明:另n=m*p^k,m为n的所有不是p的质因数的积,显然m和p^k互质。那么phi(n)=phi(m)*phi(p^k)=(p-1)*p^(k-1)*phi(m)。
phi(n*p)=phi(p^(k+1)*m)=phi(p^(k+1))*phi(m)=(p-1)*(p^k)*phi(m)=(p-1)*p^(k-1)*phi(m)*p=phi(n)*p。
定理2:如果p是素数、并且p不是n的约数,那么phi(n*p)=phi(n)*(p-1)。
证明:p不是n的约数,则p与n互质,phi(n*p)=phi(n)*phi(p)=phi(n)*(p-1)。
可以根据上述两条定理通过筛法求出欧拉函数值:
int prime[N*5000];
int isPrime[N*5000];
int phi[N*5000];
void init()
{
prime[0]=0;
fill(phi,phi+5000001,1);
phi[1]=0;
memset(isPrime,0,sizeof(isPrime));
for(int i=2;i<=5000000;++i){
if(!isPrime[i]){
prime[++prime[0]]=i;
phi[i]=i-1;
}
for(int j=1;j<=prime[0];++j){
if((LL)i*(LL)prime[j]>5000000) break;
isPrime[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
}else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}


浙公网安备 33010602011771号