1、求给定的某个数的欧拉函数:
//写在前面
//有公式phi(n)=n*(1-(1/p1))(1-(1/p2)).....
//其中p1,p2,..为n的质因数
#include <iostream>
using namespace std;
int euler(int n)
{
int res=n,mid=n;
for(int i=2;i*i<=mid;i++)
{
if(mid%i==0)
{
res=res/i*(i-1);
while(mid%i==0)mid/=i;//先进行乘法防溢出
}
}
if(mid>1)return res/mid*(mid-1);//如果最后还剩一个因子
else return res;
}
int main()
{
int n;cin>>n;
cout<<euler(n);
}
2、求出1到N中所有数的欧拉函数,时间复杂度为N的平方
//写在前面;
//时间复杂度为N的平方的算法
#include <iostream>
#define maxn 1005
using namespace std;
int phi[maxn];
void euler()
{
phi[1]=1;
for(int i=2;i<maxn;i++)phi[i]=i;
for(int i=2;i<maxn;i++)
{
if(phi[i]==i)//当为素数的时候
{
for(int j=i;j<maxn;j+=i)
phi[j]=phi[j]/i*(i-1);//先进行除法,防溢出
}
}
}
int main()
{
euler();
for(int i=1;i<100;i++)cout<<phi[i]<<' ';
}
3、线性筛法求欧拉函数,快的飞起
//写在前面
//对于欧拉函数有如下三条性质 p为素数
//1、phi(p)=p-1
//2、当p与i互质时有: phi(p*i)=phi(p)*phi(i)
//3、当i%p==0时有:phi(p*i)=p*phi(i)
#include <iostream>
#include <string.h>
#define maxn 1005
using namespace std;
int visit[maxn];
int prime[maxn];//保存素数
int phi[maxn];//记录下标的欧拉函数
int tot;//记录素数的个数
void euler()
{
memset(visit,0,sizeof(visit));
phi[1]=1;
for(int i=2;i<maxn;i++)
{
if(!visit[i])//当i为素数时
{
prime[tot++]=i;
phi[i]=i-1;
}
for(int j=0;j<tot;j++)
{
int mid=i*prime[j];
if(mid>maxn)break;
visit[mid]=1;
if(i%prime[j]==0)
{
phi[mid]=phi[i]*prime[j];//性质3
}
else
{
phi[mid]=phi[i]*phi[prime[j]];//性质2
}
}
}
}
int main()
{
euler();
for(int i=1;i<100;i++)cout<<phi[i]<<' ';
}