数论 —— 欧拉函数
【定义】
对正整数 n,欧拉函数是小于等于 n 的数中与 n 互质的数的个数,记作:
例如:,因为 1、3、5、7 均与 8 互质。
【性质】
1)若 n 为一素数 p,则:
2)若 n 为一素数 p 的幂次 ,则:
例如:要求 ,由于 16=2*2*2*2,故
3)若 n 为任意两个互质的数 a、b 的积,则:
例如:要求 ,由于 40=5*8,且 5、8 互质,所以
4)设 为 正整数 n 的素数幂乘积表达式,则:
5)若 ,则:
6)若 ,则:
7)前 n 个数的欧拉函数的和为:
【求法】
1.一般方法
求一个数 x 的欧拉函数
int Euler(int x)
{
int res=x;
for(int i=2;i<(int)sqrt(x*1.0)+1;i++)
{
if(x%i==0)
{
res=res/i*(i-1);
while(x%i==0)/// 保证i一定是素数
x/=i;
}
}
if(x>1)
res=res/x*(x-1);
return res;
}
2.递推求法
打表取 1 到 N 的所有欧拉函数并存在数组 phi 中
int phi[N];
void Euler()
{
for(int i=1;i<=N;i++)
phi[i]=i;
for(int i=2;i<=N;i+= 2)
phi[i]/=2;
for(int i=3;i<=N;i+= 2)
{
if(phi[i]==i)
{
for(int j=i;j<=N;j+=i)
phi[j]=phi[j]/i*(i-1);
}
}
}
3.欧拉函数线性筛法
该算法可在线性时间内筛素数的同时求出所有数的欧拉函数。
如要求一个数的欧拉函数,可以用欧拉函数性质直接求出,但是如果要求前 n 个数的欧拉函数,可采用线性时间的方法筛选欧拉函数值,完成打表。
int phi[N],prime[N];
bool vis[N];
void Euler(int n)
{
int cnt=0;
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
prime[++cnt]=i;//筛素数的时先判断i是否是素数
phi[i]=i-1;//当i是素数时phi[i]=i-1
}
for(int j=1;j<=cnt;j++)
{
if(i*prime[j]>n)
break;
vis[i*prime[j]]=1;//确定i*prime[j]不是素数
if(i%prime[j]==0)//看prime[j]是否是i的约数
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else
phi[i*prime[j]]=phi[i]*(prime[j]-1);//其prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性
}
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!