http://blog.csdn.net/danliwoo/article/details/48851073(丹老师的)
http://blog.csdn.net/prime7/article/details/9732353(网上大佬的)
附上一点模板
//直接求解欧拉函数
int euler(int n){ //返回euler(n)
int res=n,a=n;
for(int i=2;i*i<=a;i++){
if(a%i==0){ //第一个找到的一定是素因子
res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出
while(a%i==0) a/=i; //把素因子全都除掉
}
}
if(a>1) res=res/a*(a-1);
return res; //最后的结果
}
//筛选法打欧拉函数表
#define Max 1000001
int euler[Max];
void Init(){
euler[1]=1;
for(int i=2;i<Max;i++)
euler[i]=i;
for(int i=2;i<Max;i++)
if(euler[i]==i)
for(int j=i;j<Max;j+=i)
euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出
}
//素数表实现
bool boo[50000];
int p[20000];//素数表
void prim()
{
memset(boo,0,sizeof(boo));
boo[0]=boo[1]=1;
int k=0;
for(int i=2; i<50000; i++)
{
if(!boo[i])
p[k++]=i;
for(int j=0; j<k&&i*p[j]<50000; j++)
{
boo[i*p[j]=1;
if(!(i%p[j]))
break;
}
}
}//筛选法打表
int phi(int n)
{
int rea=n;
for(int i=0; p[i]*p[i]<=n; i++)//对于一些不是素数的可不遍历
if(n%p[i]==0)
{
rea=rea-rea/p[i];
while(n%p[i]==0) n/=p[i];
}
if(n>1)
rea=rea-rea/n;
return rea;
}