为什么线性筛欧拉函数i%prime[j]==0的时候phi[i*prime[j]]=phi[i]*prime[j]

来源:互联网 发布:安卓小说阅读器源码 编辑:程序博客网 时间:2024/05/01 16:21

转载自@ITAK
http://blog.csdn.net/qingshui23/article/details/50969344
看贾志鹏线性筛的时候想起来的。
我有一个繁琐的证明- -。
证明ϕ(pm)=p×ϕ(m),p为素数,m∈Z.

m=pα⋅m′,α,m′∈N,(pα,m′)=1.

那么
ϕ(m)=ϕ(m′)⋅ϕ(pα).


ϕ(pα)=(p−1)pα−1

因此
ϕ(m)=ϕ(m′)⋅((p−1)pα−1).

又因为
n=p⋅m=m′⋅pα+1

显然m′和pα+1互素,所以
ϕ(n)=ϕ(m′)⋅ϕ(pα+1)=ϕ(m′)⋅p⋅(p−1)⋅pα−1=ϕ(m)⋅p

证毕。

顺便贴下欧拉函数筛法代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 50005;int n;int phi[MAXN],prime[MAXN],cnt_p;int flag_p[MAXN];void getphi(){   cnt_p = 0;   memset(flag_p,0,sizeof(flag_p)); //0为素数   flag_p[0] = 1;   flag_p[1] = 1;   phi[0] = 0;   phi[1] = 0;//???   for(int i=2; i<MAXN; ++i)   {//cout<<"xxx"<<endl;       if(!flag_p[i]) { prime[cnt_p++] = i; phi[i] = i-1; }       for(int j=0; j<cnt_p && i*prime[j]<MAXN; ++j)       {           flag_p[i*prime[j]] = 1;           if(!(i%prime[j])) { phi[i*prime[j]] = phi[i]*prime[j]; break;}             else phi[i*prime[j]] = phi[i]*(prime[j]-1);  //若p为素数,则pih[p] = p-1;       }   }   return ;}int main(){   getphi();  // for(int i=0; i<100; ++i)   //  cout<<i<<" "<<phi[i]<<endl;}
0 0