欧拉函数(求与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);
			}
		}
	}
}

  

posted @ 2016-05-02 11:44  20143605  阅读(1157)  评论(0)    收藏  举报